当用户切换到暗模式时无法让 UINavigationBar tintColor 更新

Can't get UINavigationBar tintColor to update when user switches to dark mode

在我的应用程序中,有两个主题:浅色主题和深色主题(均自定义)。它们分别在名为 LightTheme 和 DarkTheme 的 class 中定义,并且都符合 ThemeProtocol,后者简单地为每个方面定义了颜色。名为 ThemeManager 的 class 处理 switching/setting 主题和特定颜色。当用户从浅色模式更改为深色模式或相反时,设置视图控制器调用一个名为 updateColors() 的方法来反映向深色或浅色模式的切换。一切正常 - 背景颜色通过 updateColors() 方法与其他视图一样更新。唯一无法更新颜色的元素是导航栏。这会导致导航栏中的项目与背景颜色相同。

private func updateColors() {
        // other colors are changed here, works fine
        // changing the color does not work; icons are still the color they were before
        self.navigationController?.navigationBar.tintColor = UIColor.blue
    }

答案对我不起作用,因为我已经在使用答案更新导航颜色的方法。

值得一提的是,我在根视图控制器中这样配置导航栏:

let backImage = NewImages.backArrow?.withRenderingMode(.alwaysOriginal).withAlignmentRectInsets(UIEdgeInsets(top: 0, left: -Padding.intermediate, bottom: 0, right: 0))
self.navigationController?.navigationBar.backIndicatorImage = backImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        
let settingsImage = NewImages.settings?.withRenderingMode(.alwaysOriginal).withAlignmentRectInsets(UIEdgeInsets(top: 0, left: Padding.intermediate, bottom: 0, right: 0))
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: settingsImage, style: .done, target: self, action: #selector(self.settingsButtonClicked))
self.navigationItem.rightBarButtonItem?.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: Padding.intermediate)
        
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()

以上代码设置了一个后退按钮和一个转到设置视图控制器的按钮。导航栏的背景也设置为空图,使背景颜色清晰

在摆弄不同的代码组合一两个小时后,发现这是一个非常小的错误。在将代码复制并粘贴到我的问题中时,我意识到了这个问题。我正在回答我自己的问题,以帮助其他与我有同样问题的人。

在我的 Assets.xcassets 文件夹中,我的图像设置为 呈现为模板图像 这样我就不必为每个主题导入不同颜色的图像 - 我可以只更改 tintColor 以反映我想要的颜色。我的问题在于这两行(NewImages 只是我的每个图像资产具有类型 UIImage 属性的结构):

let backImage = NewImages.backArrow?.withRenderingMode(.alwaysOriginal).withAlignmentRectInsets(UIEdgeInsets(top: 0, left: -Padding.intermediate, bottom: 0, right: 0))
let settingsImage = NewImages.settings?.withRenderingMode(.alwaysOriginal).withAlignmentRectInsets(UIEdgeInsets(top: 0, left: Padding.intermediate, bottom: 0, right: 0))

如您所见,这些图像的渲染模式设置为.alwaysOriginal。我改成了.alwaysTemplate,问题解决了