StatusBar 变换
2017-09-29 本文已影响102人
永歌森林
iOS 9之后
首先,要确保plist文件中【View controller-based status bar appearance】为YES,没有添加这个key的时候,默认是YES。
图片.png
添加两个property
@property (assign, nonatomic) UIStatusBarStyle statusBarStyle; /**< 状态栏样式 */
@property (assign, nonatomic) BOOL statusBarHidden; /**< 状态栏隐藏 */
再调用 -setNeedsStatusBarAppearanceUpdate即可。
示例代码
#pragma mark - ViewController方式
- (IBAction)changeStyle:(UISegmentedControl *)sender {
if (sender.selectedSegmentIndex == 0) {
_statusBarStyle = UIStatusBarStyleDefault;
} else {
_statusBarStyle = UIStatusBarStyleLightContent;
}
[self setNeedsStatusBarAppearanceUpdate];
}
- (IBAction)statusShowOrHidden:(UISegmentedControl *)sender {
if (sender.selectedSegmentIndex == 0) {
_statusBarHidden = NO;
} else {
_statusBarHidden = YES;
}
[self setNeedsStatusBarAppearanceUpdate];
}
#pragma mark - 需要重写的几个状态栏方法
/**
* 控制状态栏的样式
* 要刷新状态栏,让其重新执行该方法需要调用{-setNeedsStatusBarAppearanceUpdate}
*
* @return 将要显示的状态栏样式
*/
- (UIStatusBarStyle)preferredStatusBarStyle
{
return _statusBarStyle;
}
/**
* 状态栏显示还是隐藏
* 要刷新状态栏,让其重新执行该方法需要调用{-setNeedsStatusBarAppearanceUpdate}
*
* @return BOOL值
*/
- (BOOL)prefersStatusBarHidden
{
return _statusBarHidden;
}
/**
* 状态栏改变的动画,这个动画只影响状态栏的显示和隐藏
*
* @return 动画效果
*/
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
return UIStatusBarAnimationSlide;
}
与UINavigaitonController , UITabBarController结合使用时
重写UINavigationController:
- (UIStatusBarStyle)preferredStatusBarStyle {
return [self.topViewController preferredStatusBarStyle];
}
其他情况
状态栏的样式、是否显示实际上是由顶层window的当前视图控制器决定的
比如我们在程序入口处创建一个新的window:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.statusWindow = [[UIWindow alloc] initWithFrame:application.statusBarFrame];
// 这里设置windowLevel 为UIWindowLevelStatusBar或者UIWindowLevelAlert都可以
self.statusWindow.windowLevel = UIWindowLevelStatusBar;
// 颜色必须为clearColor,否则会盖住状态栏的区域
self.statusWindow.backgroundColor = [UIColor clearColor];
self.statusWindow.rootViewController = [[StatusViewContrller alloc] init];
self.statusWindow.hidden = NO;
return YES;
}
为了解决这个问题,我们可以将StatusViewContrller弄成单例,然后定义两个property来控制样式和是否隐藏即可。
重写两个property的set方法,设置完属性后调用状态栏刷新方法:
static id instance = nil;
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
// 这个方法是关键
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone];
});
return instance;
}
// 重写的方法
- (UIStatusBarStyle)preferredStatusBarStyle {
return _statusBarStyle;
}
- (BOOL)prefersStatusBarHidden {
return _statusBarHidden;
}
// setter
- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle {
_statusBarStyle = statusBarStyle;
[self setNeedsStatusBarAppearanceUpdate];
}
- (void)setStatusBarHidden:(BOOL)statusBarHidden {
_statusBarHidden = statusBarHidden;
[self setNeedsStatusBarAppearanceUpdate];
}
创建了顶层window后,唯一需要注意的是顶层window和其根视图控制器的背景色必须为clearColor。