iOS暗黑模式適配(Dark Mode)

iOS開發筆記記錄

暗黑模式簡介不贅述,直接寫用法。

蘋果官方使用鏈接入口

暗黑模式的原理

  1. 其實就是將原本的資源文件,創建出兩種模式,根據不同的模式,自動獲取該樣式的資源。
  2. 每次切換系統模式的時候,系統會重新調用一些方法,重新賦值。

適配工作

對于開發者來說,適配暗黑模式,需要做的工作是:

  1. 顏色適配(文字顏色,背景顏色)
  2. 圖片適配
  3. 狀態欄適配
  4. 模式切換代理
  5. 關閉暗黑模式(或者關閉某一個頁面的暗黑模式)
  6. 其他

1. 顏色適配

iOS13之前UIColor只能代表一種顏色,但是在iOS13之后,系統提供了一些UIColor的顏色是動態的,可以在Light ModeDark Mode下顯示不同的顏色。在這里不多講,因為真是開發中,文字顏色或者背景顏色都是UI設計好的,不太可能會用到系統的。

iOS13蘋果提供了兩個專用的方法:

+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchOS);
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchOS);

一個是類方法,一個是對象方法
這兩個方法需要傳入一個Block,當系統切換模式的時候,會觸發回調。
這個block會返回一個UITraitCollection類的對象,通過其屬性userInterfaceStyle,可以得到當前是LightMode還是DarkMode
具體的用法如下:

UIColor *bgColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
        if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
            return [UIColor redColor];
        }
        else {
            return [UIColor greenColor];
        }
    }];
    
 self.view.backgroundColor =  bgColor;

我們在開發的時候可以將此方法封裝一下,方便使用。

2. 圖片適配

在Xcode的Assets.xcassets里面
添加一個icon的時候,默認是這個樣子的

圖片1

右邊有一個Appearances的選項是這樣的:
默認Appearances

默認選擇的是None
點開之后有其他選項,我們選擇支持暗黑模式。并加入另外一組資源后:
支持暗黑模式的圖片資源

這個時候我們發現,下面多了一組Dark Appearances
這就是暗黑模式下的圖片資源。
當我們切換系統模式的時候,系統會獲取其對應的圖片。
使用方法和原來的一樣,例如:

[backBtn setImage:[UIImage imageNamed:@"nav_back_white"] forState:UIControlStateNormal];
self.backImgView.image = [UIImage imageNamed:@"nav_back_white"];

3.狀態欄適配

狀態欄需要根據模式代理進行切換即可,不贅述。
代理用法??????????

4. 模式切換代理

有的時候,頁面復雜,需要根據不同的模式執行不同的操作
系統為我們提供了代理方法,當系統切換模式的時候,會回調這個方法。將我們做的操作寫在這里即可:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange: previousTraitCollection];
        
        if (@available(iOS 13.0, *)) {
            if ([UITraitCollection currentTraitCollection].userInterfaceStyle == UIUserInterfaceStyleDark) {
                [self.editBtn setImage:[UIImage imageNamed:@"navigation_bar_userInfo_editor_white"] forState:UIControlStateNormal];
                [self.moreBtn setImage:[UIImage imageNamed:@"nav_more_icon_w"] forState:UIControlStateNormal];
            } else {
                [self.editBtn setImage:[UIImage imageNamed:@"navigation_bar_userInfo_editor_black"] forState:UIControlStateNormal];
                [self.moreBtn setImage:[UIImage imageNamed:@"nav_more_icon_d"] forState:UIControlStateNormal];
            }
        } else {
            [self.editBtn setImage:[UIImage imageNamed:@"navigation_bar_userInfo_editor_black"] forState:UIControlStateNormal];
            [self.moreBtn setImage:[UIImage imageNamed:@"nav_more_icon_d"] forState:UIControlStateNormal];
        }
    }
}

5. 關閉暗黑模式(或者關閉某一個頁面的暗黑模式)

5.1關閉某一個頁面的暗黑模式

某些頁面由于設計需要,無需進行適配,或者只要顯示固定的一個模式。
那怎么做呢?

  • UIViewController與UIView 都新增一個屬性 overrideUserInterfaceStyle
  • 關于window有一個特殊情況,我們下面在6其他里面具體說。

將overrideUserInterfaceStyle設置為對應的模式即可:

if (@available(iOS 13.0, *)) {
       self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
 } else {
       // Fallback on earlier versions
 }
5.2全局暗黑模式
  1. 在Info.plist 文件中,添加UIUserInterfaceStyle key 名字為 User Interface Style 值為String,

  2. 將UIUserInterfaceStyle key 的值設置為 Light

6.其他:

  1. 設置 Window 的該屬性, 將會影響窗口中的所有內容都采用樣式,包括根視圖控制器和在該窗口中顯示內容的所有演示控制器(UIPresentationController)

所以,這里就有一個常用的功能:選擇是否跟隨系統。

如圖:


選擇是否跟隨系統

點擊選擇模式:


選擇模式

當要實現這個功能的時候,就可以用到window。


if (index== 0){
     [UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
 }else if (index == 1) {
     [UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
 }else if (index == 2) {
     [UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
 }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。