iOS开发-Status Bar设置汇总

Status bar 状态栏的隐藏

1. Info.plist 设置状态栏的全局隐藏

在 Info.plist 中添加 Status bar is initially hidden 设置为 YES ,或者在 targets -> general 勾选 Hide status bar(会自动在 Info.plist 中添加 Status bar is initially hidden 并设置为 YES ),主要是隐藏  LunchScreen(启动界面)的状态栏。

然后在 Info.plist 中添加 View controller-based status bar appearance 设置为 NO,可以隐藏所有 UIViewController 的状态栏。

特别注意:只有当 Status bar is initially hidden 设置为 YES 的时候,设置 View controller-based status bar appearance NO 才能隐藏 UIViewController 的状态栏。

2. 代码设置状态栏的全局隐藏

首先在 Info.plist 设置 View controller-based status bar appearance 设置为 NO。

然后在 AppDelegate 或 UIViewController 里实现以下代码:

[UIApplication sharedApplication].statusBarHidden = YES;

特别注意:只有当 View controller-based status bar appearance 设置为 NO 的时候,上述代码才有效果(使用代码时 Status bar is initially hidden 就无所谓了)。

3. 代码设置状态栏的局部隐藏

首先在 Info.plist 设置 View controller-based status bar appearance 设置为 YES。

然后在 UIViewController 里实现以下代码:

- (BOOL)prefersStatusBarHidden {
    return YES;
}

特别注意:只有当 View controller-based status bar appearanceiOS 设置为 YES 的时候,上述代码才有效果(使用代码时 Status bar is initially hidden 就无所谓了)。 

问题情景:在 iOS 13 使用局部隐藏 Status bar 时,从不隐藏 Status bar 的 vcA push 到 隐藏 Status bar 的 vcB 后再 pop(带动画) 回到 vcA,此时 vcA 的导航栏高度只有44,缺少了状态栏的高度(22或44),如果是 pop(不带动画)就没有问题,暂未有完美的解决办法,只能使用 pop(不带动画)或全局隐藏。

Status bar 状态栏的颜色

Status bar 状态栏分前后两部分,一个是内容部分用于显示电池、时间等,另一个是背景部分用于显示背景色或者背景图。

1. 全局设置 Status bar  状态栏的内容颜色

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
    UIStatusBarStyleDefault                                  = 0, // Automatically chooses light or dark content based on the user interface style
    UIStatusBarStyleLightContent     API_AVAILABLE(ios(7.0)) = 1, // Light content, for use on dark backgrounds
    UIStatusBarStyleDarkContent     API_AVAILABLE(ios(13.0)) = 3, // Dark content, for use on light backgrounds
} API_UNAVAILABLE(tvos);

iOS 13 之前 UIStatusBarStyleDefault 默认为深色,而 iOS 13 之后将 UIStatusBarStyleDefault 变为根据用户界面样式自动选择浅色或深色的内容颜色,新增了 UIStatusBarStyleDarkContent 供选择深色。

首先在 Info.plist 设置 View controller-based status bar appearance 设置为 NO。

然后可以在 Info.plist 设置 Status bar style 为 Default/Dark Content/Light Content。

或者在 targets -> general 里设置  Status bar style:

或者在代码中实现以下代码:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

2. 局部设置 Status bar 状态栏的内容颜色

首先在 Info.plist 设置 View controller-based status bar appearance 设置为 YES。

然后在 UIViewController 里实现以下代码:

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDefault;
}

但是当 UIViewController 嵌套在 UINavigationController 中时,会优先调用 UINavigationControllerpreferredStatusBarStyle ,所以 UIViewControllerpreferredStatusBarStyle 不会被调用。

可以添加一个继承自 UINavigationController 的子类,或者增加一个 UINavigationController 的 Category,在子类或 Category 里重写 preferredStatusBarStyle:

- (UIStatusBarStyle)preferredStatusBarStyle {
    return [self.topViewController preferredStatusBarStyle];
}

或者重写 childViewControllerForStatusBarStyle:

- (UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

3. 设置 Status bar 状态栏的背景颜色

Status bar 的背景颜色默认透明色,如果有导航栏,Status bar 的背景色就和导航栏颜色一样,如果没有就和UIViewController的背景色一样。

如果需要特别指定 Status bar 的背景颜色,可以在 UIViewController 的 Category 里添加下面的方法:

- (void)setStatusBarBackgroundColor:(UIColor *)color {
    static UIView *statusBar = nil;
    
    if (@available(iOS 13.0, *)) {
        if (!statusBar) {
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                statusBar = [[UIView alloc] init];
                statusBar.frame = [UIApplication sharedApplication].windows.firstObject.windowScene.statusBarManager.statusBarFrame;
                [[UIApplication sharedApplication].keyWindow addSubview:statusBar];
            });
        }
    }
    else {
        statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    }
    
    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
        statusBar.backgroundColor = color;
    }
}

 iOS 13 以后苹果禁止使用 KVC 直接获取和修改私有属性,为了选择兼容 iOS 13,选择手动在 keyWindow 上添加一个 statusBar,冒充系统状态栏,为了防止重复创建添加,所以使用了单例。

这样的方法可能会出现问题,比如需要隐藏状态栏时怎么办,或者状态栏的动画会不会不流畅等,暂未有解决办法。

Status bar 使用动画

typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
    UIStatusBarAnimationNone,
    UIStatusBarAnimationFade API_AVAILABLE(ios(3.2)),
    UIStatusBarAnimationSlide API_AVAILABLE(ios(3.2)),
} API_UNAVAILABLE(tvos);

1. 全局动画

首先在 Info.plist 设置 View controller-based status bar appearance 设置为 NO。

在设置 Status bar 的隐藏和样式时还可以开启动画。

//隐藏StatusBar 动画,但是以下方法 iOS 9 以后被弃用
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

//切换StatusBar文字颜色 动画,但是以下方法 iOS 9 以后被弃用
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];

2. 局部动画

首先在 Info.plist 设置 View controller-based status bar appearance 设置为 YES。

在使用局部隐藏和局部修改样式时,同样需要在 UIViewController 里局部设置动画。

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationSlide;
}

Status bar 其他

UIViewController 里还有一个 modalPresentationCapturesStatusBarAppearance 属性,开启后可以让被模态弹出的非全屏显示的 ViewController 接管对状态栏外观的控制。

例如 vcB 开启该属性,vcA 模态弹出非全屏显示的 vcB 后,此时状态栏由 vcB 控制。

猜你喜欢

转载自blog.csdn.net/qq_36557133/article/details/105183406
今日推荐