我遵循这个线程重写-preferredStatusBarStyle,但它没有被调用。 有什么选项我可以改变来启用它吗?(我在我的项目中使用xib。)


当前回答

对于iOS 13.4, UINavigationController类别中的preferredStatusBarStyle方法将不会被调用,swizzling似乎是唯一的选择,不需要使用子类。

例子:

分类标题:

@interface UINavigationController (StatusBarStyle)
+ (void)setUseLightStatusBarStyle;
@end

实现:

#import "UINavigationController+StatusBarStyle.h"
#import <objc/runtime.h>

@implementation UINavigationController (StatusBarStyle)

void (^swizzle)(Class, SEL, SEL) = ^(Class c, SEL orig, SEL new){
    Method origMethod = class_getInstanceMethod(c, orig);
    Method newMethod = class_getInstanceMethod(c, new);
    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    else
        method_exchangeImplementations(origMethod, newMethod);
};

+ (void)setUseLightStatusBarStyle {
    swizzle(self.class, @selector(preferredStatusBarStyle), @selector(_light_preferredStatusBarStyle));
}

- (UIStatusBarStyle)_light_preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}    
@end

在AppDelegate.h中的用法:

#import "UINavigationController+StatusBarStyle.h"

[UINavigationController setUseLightStatusBarStyle];

其他回答

NavigationController或TabBarController是需要提供样式的。以下是我的解决方法:https://stackoverflow.com/a/39072526/242769

在UINavigationController上,preferredStatusBarStyle不会被调用,因为它的topViewController优先于self。所以,要在UINavigationController上调用preferredStatusBarStyle,你需要改变它的childForStatusBarStyle (Swift) / childViewControllerForStatusBarStyle (ObjC)。

建议

重写你类中的UINavigationController:

class MyRootNavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    override var childForStatusBarStyle: UIViewController? {
        return nil
    }
}

非推荐替代方案

要为所有UINavigationController做这件事,你可以在一个扩展中覆盖(警告:它会影响UIDocumentPickerViewController, UIImagePickerController等),但你可能不应该根据Swift文档这样做:

extension UINavigationController {
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    open override var childForStatusBarStyle: UIViewController? {
        return nil
    }
}

Swift 3 iOS 10解决方案:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
 }

如果有人在使用UISearchController时遇到这个问题。 只需要创建一个UISearchController的新子类,然后将下面的代码添加到这个类中:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return .LightContent
}

大多数答案都不包括UINavigationController的childViewControllerForStatusBarStyle方法的良好实现。根据我的经验,你应该处理这样的情况,当透明的视图控制器在导航控制器。在这些情况下,你应该把控制传递给你的模态控制器(visibleViewController),但不要在它消失的时候。

override var childViewControllerForStatusBarStyle: UIViewController? {
  var childViewController = visibleViewController
  if let controller = childViewController, controller.isBeingDismissed {
    childViewController = topViewController
  }
  return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}