iOS 控制器修改状态栏颜色

在iOS开发中,状态栏是位于屏幕顶部的一个区域,用来显示当前设备的时间、电池状态等信息。默认情况下,状态栏的颜色是由系统自动根据App的外观样式来决定的。但是,有时候我们可能希望在某个特定的控制器中修改状态栏的颜色,以使其与界面更好地融合。本文将介绍如何在iOS控制器中修改状态栏颜色,并提供代码示例。

理解状态栏

在开始修改状态栏颜色之前,我们先来理解一下状态栏的相关概念和属性。在iOS中,状态栏是由系统管理的,每个App只有一个状态栏。状态栏的高度为20 points,但在iPhone X及更高的设备上,由于刘海屏的存在,状态栏的高度变为了44 points。我们可以通过设置状态栏的样式来改变其外观,包括颜色、透明度等。

修改状态栏样式

要修改状态栏的样式,首先需要在Info.plist文件中进行配置。在该文件中,添加一个名为"View controller-based status bar appearance"的布尔类型的键值对,并将值设置为YES。这样,我们就可以在每个控制器中单独设置状态栏的样式,而不是全局使用同一个样式。

接下来,在需要修改状态栏样式的控制器中,我们可以通过重写preferredStatusBarStyle方法来返回我们希望的状态栏样式。该方法返回一个UIStatusBarStyle枚举值,可以是以下四种之一:

  • UIStatusBarStyleDefault:默认样式,黑色文字,白色背景。
  • UIStatusBarStyleLightContent:浅色样式,白色文字,黑色背景。
  • UIStatusBarStyleDarkContent:深色样式,黑色文字,白色背景。
  • UIStatusBarStyleLightContent:浅色样式,白色文字,透明背景。

比如,我们希望在一个控制器中将状态栏的文字变为白色,背景变为黑色,可以这样实现:

// Swift
override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}
// Objective-C
- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}

修改状态栏颜色

要修改状态栏的颜色,我们可以通过在控制器中添加一个背景视图来实现。首先,在控制器的viewDidLoad方法中,创建一个与状态栏大小相同的背景视图,并设置其背景颜色为我们期望的颜色:

// Swift
override func viewDidLoad() {
    super.viewDidLoad()
    
    let statusBarView = UIView(frame: UIApplication.shared.statusBarFrame)
    statusBarView.backgroundColor = UIColor.red
    view.addSubview(statusBarView)
}
// Objective-C
- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIView *statusBarView = [[UIView alloc] initWithFrame:[UIApplication sharedApplication].statusBarFrame];
    statusBarView.backgroundColor = [UIColor redColor];
    [self.view addSubview:statusBarView];
}

上述代码将在控制器的顶部添加一个红色的背景视图,覆盖住状态栏部分,从而实现了修改状态栏颜色的效果。你可以根据需要自定义背景视图的颜色和样式。

值得注意的是,由于iOS 13及更高版本中引入了暗黑模式,为了保证在不同模式下状态栏的可读性,我们需要根据当前模式来设置状态栏的样式和背景颜色。可以通过在控制器的traitCollectionDidChange方法中更新状态栏的样式来实现:

// Swift
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    
    setNeedsStatusBarAppearanceUpdate()
}
// Objective-C
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange