1. 程式人生 > Android開發 >Adapt JDME To iOS13 DarkMode

Adapt JDME To iOS13 DarkMode

全域性關閉DarkMode

這是目前採取的方案,讓APP始終保持LightMode,在info.plsit檔案中,新增UIUserInterfaceStyle,值為Light

我們要適配DarkMode,需要將UIUserInterfaceStyle刪除。

UIColor

iOS13之前 UIColor只能表示一種顏色,從iOS13開始UIColor是一個動態的顏色,在LightModeDarkMode可以分別設定不同的顏色。

1.首先系統為我們提供了一些動態顏色,使用這種動態顏色,系統直接替我們完成了適配工作。但是系統提供的顏色不符合APP的設計規範的話,一般情況下我們用不到。
@property
(class,nonatomic,readonly) UIColor *systemBrownColor API_AVAILABLE(ios(13.0),tvos(13.0)) API_UNAVAILABLE(watchos); @property (class,readonly) UIColor *systemIndigoColor API_AVAILABLE(ios(13.0),readonly) UIColor *systemGray2Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos,watchos); ... ... 複製程式碼
2.自定義動態UIColor
UIColor *textDyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
      if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) {
          return [UIColor JMEColorWithHexString:@"#2E2D2D"];
      } else {
          return
[UIColor yellowColor]; } }]; _nameLabel.textColor = textDyColor; 複製程式碼

這樣當系統切換DarkMode/LightMode時,會回撥(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider這個block,自動為我們更新顏色。

圖片資源

JDME目前使用了Assets.xcassets來管理圖片,適配DarkMode還是比較方便的。

開啟Assets.xcassets,設定AppearanceAny,Dark

將設計師提供的DarkMode素材圖片拖入對應的位置,還像往常一樣使用圖片就可以了。

[_logoImage setImage:[UIImage imageNamed:@"icon_logo"]];
複製程式碼

獲取當前模式(LightMode/DarkMode)

上面提到的顏色和圖片,都是由系統來幫我們完成切換的。但是在某些場景下,我們需要根據當前的模式,來做一些其他的適配需求。

我們可以在 UIViewController 或者 UIView 中呼叫traitCollection.userInterfaceStyle來獲取當前檢視的模式。

    
    if (@available(iOS 13.0,*)) {
        UIUserInterfaceStyle style = self.traitCollection.userInterfaceStyle;
        if (style == UIUserInterfaceStyleLight) {
            ///TODO:...
        } else {
            ///TODO:...
        }
    }
    
複製程式碼

userInterfaceStyleiOS12出現的,但是暗黑模式是iOS13才有的,所以為了避免不必要的影響,我們還是加上@available(iOS 13.0,*) 的判斷條件。

適當的時候我們可能還需要在drawRect/layoutSubViews等方法中,根據當前的模式重新設定一些色值。

監聽模式的切換(LightMode/DarkMode)

無論是LightMode還是DarkMode,使用者都可以切出APP,或者下拉控制中心浮層來隨意切換,所以我們還需要監聽模式的切換。

UIViewUIViewController 中,當模式切換時,就會觸發下面這個方法

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    if (@available(iOS 13.0,*)) {
        if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
            ///TODO:...
        }
    } else {
        // Fallback on earlier versions
    }
}
複製程式碼

CGColor

對於CGColor,我們可以使用上述的獲取當前模式和監聽模式的方式來處理不同的CGColor

Status Bar

之前 Status Bar 有兩種狀態,defaultlightContent

現在 Status Bar 有三種狀態,default,darkContentlightContent

現在的 darkContent 對應之前的 default,現在的 default 會根據情況自動選擇 darkContentlightContent

JDME中設定狀態列顏色的地方有很多,這個還得具體情況具體分析。

UIActivityIndicatorView

之前的 UIActivityIndicatorView 有三種 style 分別為 whiteLarge,whitegray現在全部廢棄

增加兩種 style 分別為 mediumlarge,指示器顏色用 color 屬性修改。

NSAttributedString

對於UILabelUITextFieldUITextView,在設定NSAttributedString時也要考慮適配Dark Mode

Storyboard/Xib

xib中,系統提供了使用colorAssets的方式,類似於圖片,但是為了相容低版本,我們還是需要手動程式碼來更改顏色,單獨適配。

第三方模組:

H5 App (WKWebview)

具體由第三方應用做適配

SDK

需要相關團隊做適配。

Flutter Module (Calendar/Login)

儘管 FlutterMaterialApp中提供了themedarkTheme兩個入口讓我們設定兩種模式下的顏色及文字樣式,但是還是需要注意一些細節,提供的樣式是否與設計師的要求一致。

注意,Flutter 1.9.1的版本並沒有適配iOS 13 Status Bar新增的UIStatusBarStyleDarkContent

ReactNative Module (JoySpace)

RN團隊需要做適配。

對於設計師

設計師需要提供一套設計規範,作為底層顏色自動轉換的對映表。我們使用系統提供的方案,可以很快做到顏色轉換來適配暗黑色模式。但是,有些顏色是需要單獨配置的,不能完全遵循底層的顏色轉換,所以,每個頁面都需要設計人員驗收,自動轉換的顏色是否符合整體頁面的UI效果,如果有變動,儘量給出一份暗黑模式的標註圖,然後我們再做單獨配置。所以,對於設計人員和開發需要適配的工作量還是蠻大的。