我遵循这个线程重写-preferredStatusBarStyle,但它没有被调用。 有什么选项我可以改变来启用它吗?(我在我的项目中使用xib。)
当前回答
Swift 4.2及以上版本
正如所选答案中提到的,根本原因是检查您的窗口根视图控制器对象。
流结构的可能情况
Custom UIViewController object is window root view controller Your window root view controller is a UIViewController object and it further adds or removes navigation controller or tabController based on your application flow. This kind of flow is usually used if your app has pre login flow on navigation stack without tabs and post login flow with tabs and possibly every tab further holds navigation controller. TabBarController object is window root view controller This is the flow where window root view controller is tabBarController possibly every tab further holds navigation controller. NavigationController object is window root view controller This is the flow where window root view controller is navigationController. I am not sure if there is any possibility to add tab bar controller or new navigation controller in an existing navigation controller. But if there is such case, we need to pass the status bar style control to the next container. So, I added the same check in UINavigationController extension to find childForStatusBarStyle
使用以下扩展,它处理所有上述场景-
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController?.childForStatusBarStyle ?? selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return topViewController?.childForStatusBarStyle ?? topViewController
}
}
extension AppRootViewController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return children.first { $0.childForStatusBarStyle != nil }?.childForStatusBarStyle?.preferredStatusBarStyle ?? .default
}
}
在info中你不需要UIViewControllerBasedStatusBarAppearance键。Plist默认为true
对于更复杂的流程,需要考虑的要点
In case you present new flow modally, it detaches from the existing status bar style flow. So, suppose you are presenting a NewFlowUIViewController and then add new navigation or tabBar controller to NewFlowUIViewController, then add extension of NewFlowUIViewController as well to manage further view controller's status bar style. In case you set modalPresentationStyle other than fullScreen while presenting modally, you must set modalPresentationCapturesStatusBarAppearance to true so that presented view controller must receive status bar appearance control.
其他回答
iOS 7中的UIStatusBarStyle
iOS 7的状态栏是透明的,它后面的视图是透视的。
状态栏的样式是指其内容的外观。在ios7中,状态栏内容要么是暗的(UIStatusBarStyleDefault),要么是亮的(UIStatusBarStyleLightContent)。uistatusbarstyleblack半透明和UIStatusBarStyleBlackOpaque在iOS 7.0中已弃用。使用UIStatusBarStyleLightContent代替。
如何改变UIStatusBarStyle
如果状态栏下面是一个导航栏,状态栏的样式将被调整以匹配导航栏的样式(UINavigationBar.barStyle):
具体来说,如果导航栏样式是UIBarStyleDefault,状态栏样式将是UIStatusBarStyleDefault;如果导航栏样式是UIBarStyleBlack,状态栏样式将是UIStatusBarStyleLightContent。
如果状态栏下面没有导航栏,状态栏样式可以在应用程序运行时由单个视图控制器控制和更改。
-[UIViewController preferredStatusBarStyle]是ios7新增的方法。它可以被重写以返回首选的状态栏样式:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
如果状态栏样式应该由子视图控制器控制,而不是由self控制,重写-[UIViewController childViewControllerForStatusBarStyle]以返回子视图控制器。
如果你想选择退出这个行为,并通过使用-[UIApplication statusBarStyle]方法设置状态栏样式,添加UIViewControllerBasedStatusBarAppearance键到应用程序的信息。plist文件并给它赋值NO。
从Xcode 11.4开始,覆盖UINavigationController扩展中的preferredStatusBarStyle属性不再有效,因为它将不会被调用。
将navigationBar的barStyle设置为.black确实有效,但如果你向navigationBar添加子视图,它可能在明暗模式下具有不同的外观,则会添加不必要的副作用。因为通过将barStyle设置为黑色,嵌入在navigationBar中的视图的userInterfaceStyle将始终具有userInterfaceStyle。不管应用程序的userinterfacstyle是暗的。
我提出的正确解决方案是通过添加UINavigationController的子类并覆盖preferredStatusBarStyle。如果你使用这个自定义的UINavigationController为你所有的视图,你将在保存侧。
在Swift中,对于任何类型的UIViewController:
在你的AppDelegate集合中:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = myRootController
return true
}
myRootController可以是任何类型的UIViewController,例如UITabBarController或UINavigationController。
然后,像这样重写这个根控制器:
class RootController: UIViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
这将改变状态栏在整个应用程序中的外观,因为根控制器只负责状态栏的外观。
记住在你的信息中将基于视图控制器的状态栏外观属性设置为YES。Plist使其工作(这是默认值)。
大多数答案都不包括UINavigationController的childViewControllerForStatusBarStyle方法的良好实现。根据我的经验,你应该处理这样的情况,当透明的视图控制器在导航控制器。在这些情况下,你应该把控制传递给你的模态控制器(visibleViewController),但不要在它消失的时候。
override var childViewControllerForStatusBarStyle: UIViewController? {
var childViewController = visibleViewController
if let controller = childViewController, controller.isBeingDismissed {
childViewController = topViewController
}
return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
对于任何使用UINavigationController的人:
UINavigationController不会转发preferredStatusBarStyle调用给它的子视图控制器。相反,它管理自己的状态——就像它应该做的那样,它在屏幕顶部绘制状态栏,因此应该对状态栏负责。因此,在导航控制器中实现preferredStatusBarStyle在vc中什么都不会做——它们永远不会被调用。
诀窍是UINavigationController使用什么来决定UIStatusBarStyleDefault或uistatusbarstyelightcontent返回什么。它基于它的UINavigationBar.barStyle。默认的(UIBarStyleDefault)导致前景UIStatusBarStyleDefault状态栏为黑色。UIBarStyleBlack会给出一个uistatusbarstyelightcontent状态栏。
TL; diana:
如果你想在UINavigationController上使用UIStatusBarStyleLightContent:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
推荐文章
- 如何停止不必要的UIButton动画标题变化?
- 是否有可能更新一个本地化的故事板的字符串?
- 以编程方式获取Bundle Identifier
- 为iPad和iPhone设计输入按钮
- 如何在我的iPhone应用程序中使用NSError ?
- 我的预发行应用已经在iTunes Connect中“处理”了一周多,这是怎么回事?
- Xcode iOS项目只显示“我的Mac 64位”,但不显示模拟器或设备
- Objective-C中的自动引用计数不能防止或减少什么样的泄漏?
- 在Xcode 9中如何从打开的多个模拟器中退出或关闭单个模拟器?
- 如何使用Swift播放声音?
- UINavigationBar自定义返回按钮没有标题
- 如何精确地以毫秒为单位记录方法的执行时间?
- 在整个UIWindow中获取UIView的位置
- 如何解散ViewController在Swift?
- 保存字符串到NSUserDefaults?