iOS开发中,我们经常遇到改变状态栏的情况(显示不显示,白底黑字,黑底白字等等)
第一种处理方式
由UIApplication处理,一种比较暴力的方式去处理
打开项目的.plist文件
上面的这种格式是苹果默认的格式,看着不是很爽,我更喜欢下面的这种方式打开,当然也可以以XML方式打开,看个人爱好了,添加UIViewControllerBasedStatusBarAppearance这个key,value赋值为NO,字面意思:状态栏的显示不基于UIViewController,也就是说ViewController没有改变状态栏的权利
好的,准备工作已经做好了,直接上源码:
感兴趣的可以直接粘贴复制跑一下
//
// TestViewController.m
// status_bar_test
//
// Created by shaolin on 16/3/9.
// Copyright © 2016年 shaolin. All rights reserved.
//
#import "FirstViewController.h"
@interface FirstViewController ()
@property (nonatomic,strong)UIButton* btn;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"status bar test";
self.view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:self.btn];
}
- (UIButton*)btn {
if (!_btn) {
_btn = [UIButton buttonWithType:UIButtonTypeSystem];
_btn.frame = CGRectMake(0, 64, 375, 100);
_btn.backgroundColor = [UIColor grayColor];
[_btn setTitle:@"test" forState:UIControlStateNormal];
[_btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
}
return _btn;
}
- (void)test {
static BOOL b = YES;
if (b) {
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
} else {
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
}
b = !b;
}
@end
statusBarStyle,苹果提供了四个枚举
但是,我给其赋值的时候看到了这样的情况:
很显然下面的两个枚举苹果已经不建议使用了
控制status bar是否显示
[UIApplication sharedApplication].statusBarHidden = YES;
请注意
上面所有的操作都是基于sharedApplication的,所以修改后即为全局修改,如果只想在某个ViewController使用,又想用这种暴力的方式,那就需要在VC生命周期的最后将其改变回来
第二种处理方式
status bar显示控制权交给ViewController
#import "FirstViewController.h"
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
@end
运行结果:
请注意
当我们的VC(ViewController的简称)是基于UINavigationController这种形式的时候,这种处理方式只能控制status bar显示不显示,并不能控制其style,亲测,如下代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FirstViewController* vc = [FirstViewController new];
UINavigationController* navVc = [[UINavigationController alloc]initWithRootViewController:vc];
self.window.rootViewController = navVc;
return YES;
}
//
// status_bar_test
//
// Created by shaolin on 16/3/9.
// Copyright © 2016年 shaolin. All rights reserved.
//
#import "FirstViewController.h"
static BOOL b = NO;
@interface FirstViewController ()
@property (nonatomic,strong)UIButton* btn;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"status bar test";
self.view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:self.btn];
}
- (UIButton*)btn {
if (!_btn) {
_btn = [UIButton buttonWithType:UIButtonTypeSystem];
_btn.frame = CGRectMake(0, 64, 375, 100);
_btn.backgroundColor = [UIColor grayColor];
[_btn setTitle:@"test" forState:UIControlStateNormal];
[_btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
}
return _btn;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationFade;
}
- (BOOL)prefersStatusBarHidden {
return b;
}
//- (UIStatusBarStyle)preferredStatusBarStyle {
// if (b) {
// return UIStatusBarStyleLightContent;
// }
// return UIStatusBarStyleDefault;
//}
- (void)test {
b = !b;
//这个方法会通知系统去调用当前UIViewController的**preferredStatusBarStyle**方法
[self setNeedsStatusBarAppearanceUpdate];
}
@end
那这种情况下怎么去控制呢?
解决方案:
- 自定义一个UINavigationController
- 重写 - (UIViewController *)childViewControllerForStatusBarStyle 方法
#import "MyNavController.h"
@interface MyNavController ()
@end
@implementation MyNavController
- (void)viewDidLoad {
[super viewDidLoad];
}
/**
* 默认返回值为nil。
* 当我们调用setNeedsStatusBarAppearanceUpdate时,系统会调用application.window的rootViewController的preferredStatusBarStyle
* 方法
* 我们的程序里一般都是用UINavigationController做root,如果是这种情况,那我们自己的UIViewController里的preferredStatusBarStyle根本不会被调用
* 这个时候不要调用我自己(就是UINavigationController)的preferredStatusBarStyle方法,而是去调用navigationController.topViewController的preferredStatusBarStyle方法
*
* @return stack最上层的vc,我们知道navigation是以stack的形式跳转的
*/
- (UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}
@end
AppDelegate.m文件,用自定义的NavigationController作为window的rootViewController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FirstViewController* vc = [FirstViewController new];
MyNavController* navVc = [[MyNavController alloc]initWithRootViewController:vc];
self.window.rootViewController = navVc;
return YES;
}
效果图:
附上GitHib源码地址:
status_bar_test
如果两种方式同时在项目中怎么办?
取info.plist中 UIViewControllerBasedStatusBarAppearance中的设置:
NSNumber *isVCBasedStatusBarAppearanceNum = [[NSBundle mainBundle]objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"];
设为YES时isVCBasedStatusBarAppearanceNum值为1
设为NO时isVCBasedStatusBarAppearanceNum值为0
根据这个去处理你的逻辑哈
希望会给大家带来帮助O(∩_∩)O