IOS的项目多数会遇到控制状态栏和导航栏的问题,比如隐藏状态栏、控制状态栏的文字颜色等。遇见坑了,所以总结了一下用法。。。
首先,IOS的界面分为状态栏和导航栏,状态栏是指显示电池、时间的最顶部的一个窄条,高度为20个点;而导航栏是紧接着状态栏的44个点高度的横条,一般用于显示app标题,返回按钮等操作按钮。
状态栏控制
对状态栏的控制分两种情况:全局设置和分页面设置。控制这两种模式的开关是info.plist
文件的View controller-based status bar appearance
配置项。
全局设置状态栏
将info.plist
文件的View controller-based status bar appearance
设置为NO
,即可开启全局设置,也就是说你在VC中对状态栏的控制都将无效,或者是通过下面的代码来全局控制:
//设置状态栏的字体颜色模式
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
//设置状态栏是否隐藏
[[UIApplication sharedApplication] setStatusBarHidden:YES];
注意,我们并不能对状态栏的字体颜色做任意的控制,只有两种选择UIStatusBarStyleDefault
和UIStatusBarStyleLightContent
,前者是默认的黑色,而后者是白色。也就是说如果你的背景色是偏深色,那么设置状态栏的字体颜色为白色。另外,我们可以全局设置状态栏是否显示,但是一般而言app不会对所有界面都不显示状态栏,而是只在特定的页面需要隐藏状态栏,比如对于视频播放界面不希望显示状态栏。
对于状态栏的背景色设置,上面提到从ios7开始状态栏本身实际上是透明的,它的背景色其实取决于导航栏的背景色。导航栏的控制见这篇文章
分页面设置状态栏
将info.plist
文件的View controller-based status bar appearance
设置为YES
,即可开启由VC来控制状态栏的功能,在这种模式下,全局的设置将无效!!所以我们必须逐个页面对状态栏进行设置,否则状态栏将维持默认的黑色字体和默认为显示状态。
字体设置
对于设置状态栏字体颜色,分两种情况:VC是否属于UINavigationController
中:
- 当VC不在
UINavigationController
中时,在VC中添加一个方法
- (UIStatusBarStyle)preferredStatusBarStyle
{
//返回白色
return UIStatusBarStyleLightContent;
//返回黑色
//return UIStatusBarStyleDefault;
}
保险起见,在view的某个加载阶段比如viewWillAppear
中,执行:
[self setNeedsStatusBarAppearanceUpdate];
- 当VC在
UINavigationController
中时,VC并不能通过1)的方式控制状态栏的颜色,详见本文后面的参考资料,那么这个时候,有一个trick的方法可以在VC中间接的控制:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
隐藏控制
对于控制状态栏的隐藏同样存在VC是否是根控制器的问题,也就说只有根控制器才能直接控制状态栏的显示与否。
- 如果是VC本身就是根控制器,那么在VC中添加如下代码:
- (BOOL)prefersStatusBarHidden {
return YES;
}
当然,保险起见,在适当的时候调用
[self setNeedsStatusBarAppearanceUpdate];
- 如果VC不是根控制器,那么不像控制字体颜色那样有trick,我们只能间接的通过在子VC中控制根VC,从而间接控制根控制器。那么这个方法就很多了,比如我的根VC是个tab的VC,首先现在tab的VC中,实现1):
@interface YYCTabBarController : RDVTabBarController
//定义一个变量来控制状态栏显示,子VC通过修改这个值来间接控制
@property (nonatomic,assign)BOOL statusBarHidden;
@end
@implementation YYCTabBarController
- (BOOL)prefersStatusBarHidden {
return _statusBarHidden;
}
@end
在子VC中:
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//rdv_tabBarController指向YYCTabBarController
if([self.rdv_tabBarController respondsToSelector:@selector(setStatusBarHidden:)]){
[self.rdv_tabBarController performSelector:@selector(setStatusBarHidden:) withObject:@(YES)];
[self setNeedsStatusBarAppearanceUpdate];
}
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
if([self.rdv_tabBarController respondsToSelector:@selector(setStatusBarHidden:)]){
//注意对NO的情况,不能传@NO,只能传nil才能被当成NO
[self.rdv_tabBarController performSelector:@selector(setStatusBarHidden:) withObject:nil];
[self setNeedsStatusBarAppearanceUpdate];
}
}
可以看到在子VC中通过设置根VC的属性,并调用setNeedsStatusBarAppearanceUpdate
后,根VC的prefersStatusBarHidden
就会被调用,从而隐藏或显示状态栏。
网友评论