我遵循这个线程重写-preferredStatusBarStyle,但它没有被调用。 有什么选项我可以改变来启用它吗?(我在我的项目中使用xib。)
当前回答
在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
}
}
其他回答
对于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];
在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
}
}
从Xcode 11.4开始,覆盖UINavigationController扩展中的preferredStatusBarStyle属性不再有效,因为它将不会被调用。
将navigationBar的barStyle设置为.black确实有效,但如果你向navigationBar添加子视图,它可能在明暗模式下具有不同的外观,则会添加不必要的副作用。因为通过将barStyle设置为黑色,嵌入在navigationBar中的视图的userInterfaceStyle将始终具有userInterfaceStyle。不管应用程序的userinterfacstyle是暗的。
我提出的正确解决方案是通过添加UINavigationController的子类并覆盖preferredStatusBarStyle。如果你使用这个自定义的UINavigationController为你所有的视图,你将在保存侧。
如果你的viewController在UINavigationController下面。
子类UINavigationController并添加
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
ViewController的preferredStatusBarStyle将被调用。
在我的例子中,我意外地将视图/导航控制器呈现为UIModalPresentationStyle。overFullScreen,这导致preferredStatusBarStyle没有被调用。切换回UIModalPresentationStyle后。全屏,一切正常。
推荐文章
- 如何删除默认的导航栏空间在SwiftUI导航视图
- Ios模拟器:如何关闭应用程序
- 如何在iOS中使用Swift编程segue
- Swift -整数转换为小时/分钟/秒
- Swift:声明一个空字典
- 在成功提交我的应用程序后,“太多符号文件”
- 首先添加一个UIView,甚至是导航栏
- 我如何改变UIButton标题颜色?
- 在Swift中如何调用GCD主线程上的参数方法?
- NSLayoutConstraints是可动画的吗?
- iOS -构建失败,CocoaPods无法找到头文件
- CFNetwork SSLHandshake iOS 9失败
- 请求失败:不可接受的内容类型:文本/html使用AFNetworking 2.0
- 缺少推荐的图标文件-该包不包含iPhone / iPod Touch的应用程序图标,像素为“120x120”,png格式
- 以编程方式创建segue