iOS13 DarkMode適配(二)

級別: ★☆☆☆☆
標簽:「iOS 13」「Dark Mode」
作者: WYW
審校: QiShare團隊


筆者最近看了DarkMode相關的內容。本文將會講解亮/暗模式切換時statusBar(狀態欄)、UIActivityIndicatorView(活動指示器視圖)、文字繪制顏色及設置layer,border顏色、UIVisualEffectView適配DarkMode的相關內容。

StatusBar

打算做DarkMode適配的開發者需要注意使用的statusBar的類型。

  • 使用UIStatusBarStyleLightContent類型statusBar的開發者需要注意Light模式下,狀態欄部分的內容是無法看清的。

  • 接下來想使用UIStatusBarStyleDarkContent類型statusBar的開發者需要注意Dark模式下,狀態欄部分的內容是無法看清的。

  • 除了我們想要App或某些界面只能支持DarkMode或者支持LightMode的情況,我們要使用UIStatusBarStyleDefault類型的statusBar。

不同類型的狀態欄在亮、暗模式下的相關示意圖如下:

qiLightStatusBar1.png
qiLightStatusBar2.png
qiLightStatusBar3.png
qiDarkStatusBar11.png
qiDarkStatusBar22.png
qiDarkStatusBar33.png

示例代碼

- (UIStatusBarStyle)preferredStatusBarStyle {
    
    return UIStatusBarStyleDefault;
}

更多狀態欄顯示樣式的內容,大家可以查看dac_1033關于iOS 狀態欄、導航欄的幾處筆記

UIActivityView

使用UIActivityIndicatorView的UIActivityIndicatorViewStyleWhiteLarge的開發者需要注意,UIActivityIndicatorViewStyleWhiteLarge樣式的UIActivityIndicatorView無法在DarkMode模式下基本看不見。其中MBProgressHUD使用過UIActivityIndicatorView,不過因為MBProgressHUD在外側嵌套了一層黑色容器視圖,所以在Dark模式下運行效果尚可。

推薦開發者使用UIActivityIndicatorViewStyleLarge或UIActivityIndicatorViewStyleMedium類型的UIActivityIndicatorView。

相關示意圖如下,可看出只有中間的UIActivityIndicatorViewStyleLarge類型的UIActivityIndicatorView可以再亮、暗模式下均能正常使用,當然開發者也可以選擇去改變UIActivityIndicatorView的tintColor來適配DarkMode。

QiActivityView1.png
QiActivityView2.png
QiActivityView3.png

示例代碼

    UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];

繪制文字顏色和CGColor

繪制文字顏色

如果我們使用drawRect繪制屬性字符串時,沒有指定顏色,系統會默認為文字顏色為黑色。或者之前我們設置的是較暗的一個顏色。相關情況在Dark模式下,相應文字基本會看不清楚。

示意圖如下:

QiDrawTextColorUnNormal.png
QiDrawTextColorNormal.png

那么為了繪制的文字在切換亮/暗模式的時候可以正常顯示,我們需要指定繪制的文字的顏色。比如明確設置

textAttris[NSForegroundColorAttributeName] = [UIColor labelColor];
注意字符串屬性字典nil Value

因為指定字符串屬性字典的方式不同,當創建字符串的屬性字典的時候,大家可能會遇到如下的一個問題。

exception:*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]

上述錯誤是往字典中插入nil的一種異常提示。即此時,我們要注意[UIColor colorNamed:@"colorName"] 的值不為空。

    if (@available(iOS 13.0, *)) {
        UIColor *forgroundColor = [UIColor colorNamed:@"colorName"];
        if (forgroundColor) {
            NSAttributedString *attriString = [[NSAttributedString alloc] initWithString:@"QiShare" attributes:@{NSForegroundColorAttributeName: forgroundColor}];
            NSLog(@"屬性字符串%@", attriString);
        }
    }

CGColor

使用到CGColor的部分,如設置Layer顏色,border顏色。設置Layer顏色會發現在亮、暗模式切換的時候,不能順利地得以切換,可以在適當的時機進行顏色設置,筆者認為可以在traitCollectionDidChange的時候多設置一次相應的顏色以避免某些切換不流暢現象。

相關示意圖如下。

QiLayerBorderColor1.png
QiLayerBorderColor2.png

截圖中的2個視圖,上邊的視圖不能隨著亮/暗模式做相應切換。下邊的視圖可以隨著亮/暗模式做相應切換。

相關實現可以在- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection 中操作。

示例代碼:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    
    if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
        self.normalColorLayer.backgroundColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
            if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
                return [UIColor redColor];
            } else {
                return [UIColor blueColor];
            }
        }].CGColor;
        self.normalColorLayer.borderColor = [UIColor systemBackgroundColor].CGColor;
    }
}

UIVisualEffectView

關于UIVisualEffectView,筆者了解得比較少,Xs·H 也提到相關場景還有應用退到后臺的時候的模糊遮罩。根據官方Demo和文檔做了如下效果的圖,大家有需要可以下載QiDarkMode查看相關代碼實現。

官方文檔相關描述:
Visual-effect views add transparency to your background views, which gives your UI more visual depth than if the backgrounds were opaque. To ensure that your content remains visible, visual-effect views blur the background content subtly and add vibrancy effects to adjust the colors of your foreground content automatically. The system updates these effects dynamically, ensuring that your app's content remains visible when the underlying content changes.

QiVisualEffectView.png

示例代碼:

   // 創建UIVisualEffectView
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleSystemThinMaterial];
    UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    visualEffectView.frame = CGRectMake(.0, 100.0, CGRectGetWidth(self.view.frame), 150.0);
    [self.view addSubview:visualEffectView];
    
    // 創建UIVibrancyEffect
    UIVibrancyEffect *vibrancyEffect =
    [UIVibrancyEffect effectForBlurEffect:blurEffect style:UIVibrancyEffectStyleSecondaryLabel];
    UIVisualEffectView *vibrancyView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect];
    [visualEffectView.contentView addSubview:vibrancyView];
    vibrancyView.frame = visualEffectView.bounds;
    vibrancyView.frame = CGRectMake(.0, .0, CGRectGetWidth(visualEffectView.frame), CGRectGetHeight(visualEffectView.frame) * 0.5);
    
    UILabel *label = [UILabel new];
    label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleLargeTitle compatibleWithTraitCollection:self.traitCollection];
    label.text = @"Vibrant Label1";
    [vibrancyView.contentView addSubview:label];
    label.frame = vibrancyView.bounds;

其他

固定設置App或某些界面亮/暗模式

  • 固定設置App亮/暗模式

固定亮模式:設置info.plist文件中的User Interface Style為"Light"

固定暗模式:設置info.plist文件中的User Interface Style為"Dark"

  • 固定某些頁面為亮/暗模式

方式:相應控制器重寫overrideUserInterfaceStyle。

固定亮模式:

- (UIUserInterfaceStyle)overrideUserInterfaceStyle {

    return UIUserInterfaceStyleLight;
}

固定暗模式:

- (UIUserInterfaceStyle)overrideUserInterfaceStyle {

    return UIUserInterfaceStyleDark;
}

Demo

詳情見Demo:QiDarkMode

參考學習網址


推薦文章:
2019蘋果秋季新品發布會速覽
申請蘋果開發者賬號的流程
Swift 5.1 (3) - 字符串
用Flutter 寫一個簡單頁面
5分鐘,帶你迅速上手Markdown語法
Swift 5.1 (2) - 運算符
Swift 5.1(1) - 基礎
Sign In With Apple(一)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容