动态更改 iOS 导航栏颜色(深色模式)
Dynamically Change iOS Nav Bar Color (Dark Mode)
我正在尝试在我的应用程序中实现暗模式切换 - 这将涉及在 UIViewController
已在屏幕上可见时将导航栏颜色切换为黑色。我知道如何通过设置
来做到这一点
UINavigationBar.appearance().barTintColor = .black
UINavigationBar.appearance().tintColor = .white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UINavigationBar.appearance().isTranslucent = false
但是,在 AppDelegate 中,这在这种情况下不起作用,因为它需要动态完成。
我也试过navigationController?.navigationBar.barTintColor = UIColor.white
,但这也不行。
更新:
我认为很多回复都与这个问题的目的混淆了 - 这与刚刚发布的 iOS13 黑暗模式完全无关 - 这是我想要的独立黑暗模式功能添加到我的应用程序(类似于其他应用程序,如 Messenger 等,在 iOS 13 发布之前,应用程序内有暗模式可用)。我需要做的是在 UINavigationBar 已经显示在屏幕上之后动态更新它的颜色,就像我可以通过 view.backgroundColor = .white
更改视图的背景颜色一样,这将更新实际颜色-屏幕上的时间。
您可能需要检查 UIViewController 提供的特征以确定当前界面样式,而不是手动检查版本 运行 iOS 13+。使用此方法,您可以在 Assets 文件夹中为两种外观定义颜色。
对于iOS 13 以下,您可以使用类似于@byaruah 所说的内容,但这不是全局效果。您还应该考虑将 UINavigationBar.appearance()
功能用于全局方法。
通过使导航栏半透明(在 AppDelegate
中)实现了这一点:
let barAppearance = UINavigationBar.appearance()
barAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: appRed]
barAppearance.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
barAppearance.shadowImage = UIImage()
barAppearance.isTranslucent = true
接下来我创建一个视图并将其放在导航栏后面,如下所示(使用 SnapKit):
let coverView = UIView()
cover.snp.makeConstraints {
make in
make.left.right.top.equalTo(self)
make.bottom.equalTo(self.snp.top).offset(universalNumber(num: parent!.topbarHeight))
}
其中 parent
是我的 UIViewController
而 topBarHeight
是:
extension UIViewController {
/**
* Height of status bar + navigation bar (if navigation bar exist)
*/
var topbarHeight: CGFloat {
return UIApplication.shared.statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)
}
}
最后更新我设置的颜色
coverView.backgroundColor = universalWhite()
其中
func universalWhite() -> UIColor {
let defaults = UserDefaults.standard
let darkMode = defaults.bool(forKey: "darkMode")
if darkMode {
return .black
} else {
return .white
}
}
我正在尝试在我的应用程序中实现暗模式切换 - 这将涉及在 UIViewController
已在屏幕上可见时将导航栏颜色切换为黑色。我知道如何通过设置
UINavigationBar.appearance().barTintColor = .black
UINavigationBar.appearance().tintColor = .white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UINavigationBar.appearance().isTranslucent = false
但是,在 AppDelegate 中,这在这种情况下不起作用,因为它需要动态完成。
我也试过navigationController?.navigationBar.barTintColor = UIColor.white
,但这也不行。
更新:
我认为很多回复都与这个问题的目的混淆了 - 这与刚刚发布的 iOS13 黑暗模式完全无关 - 这是我想要的独立黑暗模式功能添加到我的应用程序(类似于其他应用程序,如 Messenger 等,在 iOS 13 发布之前,应用程序内有暗模式可用)。我需要做的是在 UINavigationBar 已经显示在屏幕上之后动态更新它的颜色,就像我可以通过 view.backgroundColor = .white
更改视图的背景颜色一样,这将更新实际颜色-屏幕上的时间。
您可能需要检查 UIViewController 提供的特征以确定当前界面样式,而不是手动检查版本 运行 iOS 13+。使用此方法,您可以在 Assets 文件夹中为两种外观定义颜色。
对于iOS 13 以下,您可以使用类似于@byaruah 所说的内容,但这不是全局效果。您还应该考虑将 UINavigationBar.appearance()
功能用于全局方法。
通过使导航栏半透明(在 AppDelegate
中)实现了这一点:
let barAppearance = UINavigationBar.appearance()
barAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: appRed]
barAppearance.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
barAppearance.shadowImage = UIImage()
barAppearance.isTranslucent = true
接下来我创建一个视图并将其放在导航栏后面,如下所示(使用 SnapKit):
let coverView = UIView()
cover.snp.makeConstraints {
make in
make.left.right.top.equalTo(self)
make.bottom.equalTo(self.snp.top).offset(universalNumber(num: parent!.topbarHeight))
}
其中 parent
是我的 UIViewController
而 topBarHeight
是:
extension UIViewController {
/**
* Height of status bar + navigation bar (if navigation bar exist)
*/
var topbarHeight: CGFloat {
return UIApplication.shared.statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)
}
}
最后更新我设置的颜色
coverView.backgroundColor = universalWhite()
其中
func universalWhite() -> UIColor {
let defaults = UserDefaults.standard
let darkMode = defaults.bool(forKey: "darkMode")
if darkMode {
return .black
} else {
return .white
}
}