iOS13适配深色模式(Dark Mode)的实现

2020-03-27 13:57:29王振洲

未设置过背景颜色或者文字颜色的组件, 在Dark Mode模式下, 就是黑色的
这里我们就需要真对该单独App强制设置成Light Mode模式

// 设置改属性, 只会影响当前的视图, 不会影响前面的controller和后续present的controller
@available(iOS 13.0, *)
open var overrideUserInterfaceStyle: UIUserInterfaceStyle

// 使用示例
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
 super.traitCollectionDidChange(previousTraitCollection)
 
 // 每次模式改变的时候, 这里都会执行
 if (previousTraitCollection?.userInterfaceStyle == .dark) {
  // 在Dark模式下, 强制改成Light模式
  overrideUserInterfaceStyle = .light
 }
}

强制项目的显示模式

上面这种方式只能针对某一个页面修改, 如果需要对整个项目禁用Dark模式

可以通过修改window的overrideUserInterfaceStyle属性

在Xcode11创建的项目中, window从AppDelegate移到SceneDelegate中, 添加下面这段代码, 就会做到全局修改显示模式

let scene = UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate
scene?.window?.overrideUserInterfaceStyle = .light

在之前的项目中, 可以在AppDelegate设置如下代码

window.overrideUserInterfaceStyle = .light

我创建的简单项目, 上述代码的确会强制改变当前的模式, 但是状态栏的显示不会被修改, 不知道是不是漏了什么

终极方案

需要在info.plist文件中添加User Interface Style配置, 并设置为Light

<key>UIUserInterfaceStyle</key>
<string>Light</string>

问题又来了, 即使做了上面的修改, 在React Native中, 状态栏的依然是根据不同的模式显示不同的颜色, 该如何处理嘞?

Status Bar更新

在iOS13中苹果对于Status Bar也做了部分修改, 在iOS13之前

public enum UIStatusBarStyle : Int {
 case `default` // 默认文字黑色

 @available(iOS 7.0, *)
 case lightContent // 文字白色
}

从iOS13开始UIStatusBarStyle一共有三种状态

public enum UIStatusBarStyle : Int {
 case `default` // 自动选择黑色或白色

 @available(iOS 7.0, *)
 case lightContent // 文字白色
 
 @available(iOS 13.0, *)
 case darkContent // 文字黑色
}

在React Native的代码中, 设置状态栏的颜色为黑色, 代码如下

<StatusBar barStyle={'dark-content'} />

上面这段代码在iOS13系统的手机中是无效的

虽然上面的代码中设置了dark-content模式, 但是在iOS原生代码中dark-content实际是UIStatusBarStyleDefault

在文件RCTStatusBarManager.m中