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。
上一篇下一篇

猜你喜欢

热点阅读