是否有办法在保持UIViewControllerBasedStatusBarAppearance
启用的同时设置默认状态栏样式?
这是问题所在,我正在处理:
几乎整个应用都需要使用UIStatusBarStyle.LightContent
,因为导航栏背景较暗。最初,UIViewControllerBasedStatusBarAppearance
已被停用,并且在Info.plist
中为文本状态状态栏设置了以下内容:
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
这个工作正常,直到我发现这个.LightContent
状态栏甚至显示为某些共享扩展名,例如Facebook Messenger,导致它不可读:
这可以通过使用UIViewControllerBasedStatusBarAppearance
来解决,但是我需要将以下方法添加到我想要避免的所有视图控制器中,因为应用程序非常大。
此外,对于具有轻型导航栏背景的应用程序中的一个屏幕,我使用UIApplication.sharedApplication().setStatusBarStyle()
切换到黑暗导航栏,但此方法在iOS 9中已弃用。
任何想法如何解决这个问题?混写?
答案 0 :(得分:3)
我经常使用的解决方案是创建一个基本视图控制器类,我的应用程序中的所有视图控制器都派生自该类。这样做的好处是允许使用基于视图控制器的状态栏样式设置功能,使用默认(浅色或深色)样式,然后可以根据需要在每个视图控制器的基础上覆盖它。
一旦您开始进入基于特征收集的更改,大多数视图控制器所需的自定义转换动画,分析跟踪的中心点以及其他有用的东西,基本视图控制器也非常方便。
是的,您必须浏览可能较大的源代码库并将所有UIViewController
更改为BaseViewController
,但这通常与全局搜索和替换一样简单。
以下是BaseViewController
与状态栏相关方法的含义:
class BaseViewController: UIViewController {
var statusBarHidden: Bool = false { didSet { setNeedsStatusBarAppearanceUpdate() } }
var statusBarStyle: UIStatusBarStyle = .lightContent { didSet { setNeedsStatusBarAppearanceUpdate() } }
var statusBarUpdateAnimation: UIStatusBarAnimation = .fade { didSet { setNeedsStatusBarAppearanceUpdate() } }
override var preferredStatusBarStyle: UIStatusBarStyle { return statusBarStyle }
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { return statusBarUpdateAnimation }
override var prefersStatusBarHidden: Bool { return statusBarHidden }
}
对于使用默认灯光样式的所有视图控制器,您无需执行任何特殊操作:
class ViewController: BaseViewController { }
如果您需要黑暗状态栏,请执行以下操作:
class DarkStatusBarViewController: BaseViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
statusBarStyle = .default
}
}
另请注意,您可以将DarkStatusBarViewController
上方的DarkStatusBarBaseViewController
重命名为BaseViewController
,并在需要黑暗状态栏时从其{而不是BaseViewController
派生。然后,您不需要在需要它的每个视图控制器中复制状态条形码,并且您为所有
功能保持良好的线性关系。
答案 1 :(得分:3)
如何实现这一目标的最简单,最简洁的方法是在AppDelegate
的{{1}}方法中添加以下行:
application:willFinishLaunchingWithOptions
只要您的应用使用UINavigationBar.appearance().barStyle = .Black
,这会将.LightContent
作为默认状态栏样式通过应用。
如果要在启动闪屏期间使用UINavigationController
状态栏样式,请不要忘记在应用的Info.plist
中保留以下设置:
.LightContent
我当前的设置与许多其他应用非常相似,使用<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
作为最顶层的控制器,每个标签都有UITabBarController
堆栈。
UINavigationController
负责处理状态栏样式(应该如此),不要在其子视图控制器上调用UINavigationController
。因此,在我的案例中,实施subclassing solution proposed by par并不起作用。
进一步继承preferredStatusBarStyle()
I'm using的自定义子类也不是一个干净的解决方案。
现在,由于应用程序在应用程序本身的任何位置启用了UINavigationController
并且状态栏样式正确,UIViewControllerBasedStatusBarAppearance
和共享扩展名(如邮件,邮件等)使用正确的(SFSafariViewController
)状态栏样式。
唯一不使用正确状态栏样式的例外是问讯中提到的Facebook Messenger的共享扩展。但是,它似乎是扩展本身的一个错误,因为我尝试使用.Default
状态栏样式(例如Twitter)的所有应用程序都有相同的问题 - 从应用程序呈现的FB Messenger共享扩展程序有一个带有白色文本的状态栏。