最新更新(Xcode 10+ / Swift 4.2+)
对于任何愿意了解过去几年出现的不同方法背后的逻辑的人,本文将保持完整。同时,从Xcode 10 开始,Swift 4.2 第一种方法已被弃用并且不再受支持(即,如果您尝试使用它,它将不会生效)。Plist.info
它仍会参考您的信息,以更好地了解标志和定制实践背后的原因。
重要说明
了解自定义状态栏外观的两种方法非常重要。它们是不同的,不应混用。
第一种方法 - 整个应用程序的一种颜色(自 iOS7 以来已弃用)
在 info.plist 中,您可以找到或创建一个名为
View controller-based status bar appearance
并将其设置为NO。
它能做什么?它本质上建立了一个设置,表明在您的应用程序中,状态栏外观不是由每个视图控制器单独定义的。理解这一点非常重要。这意味着您对整个应用程序、所有屏幕都有统一的设置。有两种设置:default
,即白底黑字,或lightContent
,即黑底白字。
要设置其中一项(所有屏幕的一项设置):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent // .default
return true
}
这样您就不需要在每个视图控制器上重新建立此设置。但是,您始终可以诉诸这种方法来自愿改变外观。
第二种方法——每个视图控制器的单独颜色
这是相反的。要使其工作,请继续 info.plist 并设置
View controller-based status bar appearance
是_
这样,每当打开新的视图控制器时,如果您在UIViewController
需要的每个实例中插入此实现,状态栏样式就会单独设置:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent // .default
}
您与第一个相同,为状态栏设置深色或浅色样式,每个视图控制器单独设置。
UIKit 在两种情况下获取此属性:
- 在屏幕初始化时,在准备 UI 时。
- 在调用
setNeedsStatusBarAppearanceUpdate()
代码时。
在后一种情况下,您可以通过以下代码操作状态栏外观:
var isDark = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return isDark ? .lightContent : .default
}
func toggleAppearance() {
isDark.toggle()
}
然后,无论何时调用toggleAppearance()
,都会触发状态栏样式更改。
第三种方法——哈克!
有一个 hack 可以直接访问状态栏:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = UIColor.blue
}
return true
}
为什么要破解?如果您需要黑色或白色以外的状态栏颜色,请使用未记录的 API。您statusBar
使用 KVC 获取对象并设置其背景颜色。您以这种方式获得的对象 is UIStatusBar
,它是从属性派生的UIView
,因此自然支持backgroundColor
属性。这是肮脏的,不合法的方式,但到目前为止,这是为状态栏设置自定义颜色的唯一方法(不考虑UINavigationBar
允许完全自定义导航栏+状态栏外观的方法)。这很可能会导致您的应用被拒绝。但也许你很幸运。如果你是,在某些复杂的情况下(比如嵌套的层次结构、子导航和视图控制器),这可能是唯一的,或者至少是自定义状态栏外观不太麻烦的方法(例如,使其透明)
Xcode 10+,斯威夫特 4.2
没有其他选择了:开发人员应该让每个视图控制器定义状态栏外观,方法是将标志设置为YES(或省略此操作,因为默认情况下为 YES)并遵循上述说明。
奖金
您可能(尽管不鼓励)在复杂情况下使用基于黑客的解决方案,以便在任何阶段自愿更改状态栏外观。在颜色方面,以下扩展方法完全可以完成常规方法所能完成的工作。您可以根据自己的需要进行调整。
extension UIViewController {
func setStatusBarStyle(_ style: UIStatusBarStyle) {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
}
}
}