iOS 10、Xcode 9.2下如何实现类似Google Authenticator的状态栏差异化显隐
这个问题我之前帮朋友排查过,在iOS 10 + Xcode 9.2的环境下要实现「前台视图控制器隐藏状态栏、后台视图控制器显示状态栏」的效果,得从项目配置和视图控制器的代码设置两方面入手,我给你一步步拆解:
第一步:先搞定项目的全局状态栏权限配置
这是最容易踩坑的第一步,如果全局配置不对,后续的VC单独设置都会失效:
- 打开Xcode选中你的项目Target,进入
General标签页,找到Deployment Info区域,不要勾选Hide status bar选项; - 或者直接修改项目的
Info.plist文件,添加View controller-based status bar appearance字段,将其值设置为YES——这个是核心开关,只有开启它,每个视图控制器才能独立控制状态栏的显示/隐藏,而不是被全局设置统一接管。
第二步:给每个视图控制器单独设置状态栏规则
接下来分别给前台、后台的视图控制器添加对应的状态栏控制代码:
前台需要隐藏状态栏的VC
在你的前台视图控制器类中,重写这两个方法(Swift版本):
override var prefersStatusBarHidden: Bool { return true // 返回true表示隐藏状态栏 } override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { return .fade // 可选,设置状态栏隐藏/显示的动画效果,比如fade或slide }
如果是用Objective-C开发,代码如下:
- (BOOL)prefersStatusBarHidden { return YES; } - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation { return UIStatusBarAnimationFade; }
后台需要显示状态栏的VC
同样在后台视图控制器类中重写对应的方法(Swift版本):
override var prefersStatusBarHidden: Bool { return false // 返回false表示显示状态栏 }
Objective-C版本:
- (BOOL)prefersStatusBarHidden { return NO; }
第三步:处理导航控制器的特殊情况(如果你的VC嵌入在导航控制器里)
如果你的视图控制器是放在UINavigationController中的,默认导航控制器会接管状态栏的控制权,这时候需要自定义一个导航控制器子类,让它把控制权交还给当前显示的子VC:
Swift版本的自定义导航控制器:
class CustomNavigationController: UINavigationController { override var prefersStatusBarHidden: Bool { // 沿用当前顶部VC的状态栏设置 return topViewController?.prefersStatusBarHidden ?? false } override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { return topViewController?.preferredStatusBarUpdateAnimation ?? .fade } }
Objective-C版本:
@interface CustomNavigationController : UINavigationController @end @implementation CustomNavigationController - (BOOL)prefersStatusBarHidden { return [self.topViewController prefersStatusBarHidden]; } - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation { return [self.topViewController preferredStatusBarUpdateAnimation]; } @end
之后把项目中原有的UINavigationController替换成这个自定义子类即可。
可选:手动触发状态栏更新(如果切换VC时没自动生效)
有时候切换视图控制器后状态栏不会自动更新,这时候可以在VC的viewWillAppear方法里手动触发更新:
Swift版本:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setNeedsStatusBarAppearanceUpdate() // 通知系统更新状态栏样式 }
Objective-C版本:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self setNeedsStatusBarAppearanceUpdate]; }
按照上面的步骤设置后,就能实现前台VC隐藏状态栏、后台VC正常显示状态栏的效果了,不会再出现全局隐藏的问题。
内容的提问来源于stack exchange,提问作者dianyi
相关产品推荐
相关产品推荐

