簡體   English   中英

當用戶在設置中更改外觀時,應用程序不會更新並且 traitCollectionDidChange 不會觸發

[英]app doesn't update and traitCollectionDidChange doesn't fire when user changes appearance in settings

在我的應用程序中,我允許用戶覆蓋設備上設置的外觀。 如果他們想覆蓋系統范圍的外觀,這是處理更新 UI 的類:

class UserInterfaceStyleController {

init() {
    self.handleUserInterfaceStyleChange()
    NotificationCenter.default.addObserver(self, selector: #selector(self.handleUserInterfaceStyleChange), name: Notification.Name(OMGNotification.changeBizzaroMode.rawValue), object: nil)
}

@objc func handleUserInterfaceStyleChange() {
    if #available(iOS 13.0, *) {
        let windows = UIApplication.shared.windows
        for window in windows {
            if UIScreen.main.traitCollection.userInterfaceStyle == .light {
                if UserDefaults.standard.bizzaroMode {
                    window.overrideUserInterfaceStyle = .dark
                } else {
                    window.overrideUserInterfaceStyle = .light
                }
            }
            if UIScreen.main.traitCollection.userInterfaceStyle == .dark {
                if UserDefaults.standard.bizzaroMode {
                    window.overrideUserInterfaceStyle = .light
                } else {
                    window.overrideUserInterfaceStyle = .dark
                }
            }
            window.subviews.forEach({ view in
                view.layoutIfNeeded()
            })
        }
    }
}

這是有效的 - 用戶翻轉開關,應用程序更改 userInterfaceStyle。 問題是當用戶更改系統范圍的外觀(在設置中設置亮或暗模式)時,應用程序不會自動更改外觀,僅當他們手動設置時。

所以我假設當用戶在系統范圍內更改它時我需要做一些工作,而 traitCollectionDidChange 似乎是我需要使用的。 問題是當用戶在設置中更改外觀時它不會觸發,只有在我的應用程序中手動設置時才會觸發。 我在 viewController 中有這個代碼來測試:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    // Lots of stuff

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        print("We have a style mode change")
    }

    // Lots more stuff
}

當我手動覆蓋時,它會打印“我們有一個樣式模式更改”。 當我進入設置並切換系統范圍的外觀時,traitCollectionDidChange 不會觸發。

我發誓我在某一時刻工作得很好,但是當我使用 overrideUserInterfaceStyle 並且已經燒毀了很多代碼更改時,我一直在嘗試解決一些奇怪的問題。

我想我錯過了一些明顯的東西。 在我開始允許用戶覆蓋之前,當外觀在系統范圍內更改時,應用程序在后台自動切換,根本沒有代碼。 現在它不會並且 traitCollectionDidChange 不會觸發。 我錯過了什么或做錯了什么? 如果有幫助,很高興提供更多代碼。

謝謝!

問題是您覆蓋了用戶界面樣式,這會導致任何系統更改不會傳播到您的窗口。 您需要將overrideUserInterfaceStyle設置為.unspecified ,否則系統不會在更改時調用視圖堆棧中的traitCollectionDidChange方法。

在我們的應用程序中,我們為用戶提供三個選項:自動、亮和暗,其中每個選項只是將overrideUserInterfaceStyle設置為適當的選項。

順便說一句,您不需要在所有子視圖上調用layoutIfNeeded() — 設置overrideUserInterfaceStyle會自動觸發重繪。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM