ios - 当用户在设置中更改外观时,应用程序不会更新并且 traitCollectionDidChange 不会触发
问题描述
在我的应用程序中,我允许用户覆盖在设备上设置的外观。如果他们想要覆盖系统范围的外观,这是处理更新 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
会自动触发重绘。
推荐阅读
- java - 打印数组中具有负和的子数组的数量
- python - LSH 即时分箱
- mysql - MySQL SELECT 行基于前缀
- python - wxpython中多帧的代码布局指南
- laravel - 表不呈现(Yajra 数据表)
- mysql - 总结mysql表中的重复行
- javascript - 如何在硒中打印页面并关闭“打印”窗口
- math - 后缀符号正在改变评估中括号的优先级
- angular8 - 如何修复“错误:找不到构建器 @angular-devkit/build-angular:dev-server 的实现”
- mysql - 你能告诉我我用来检索客户上次下单时间信息的查询有什么问题吗?