iOS13 DarkMode適配(二)

級別: ★☆☆☆☆
標籤:「iOS 13」「Dark Mode」
做者: WYW
審校: QiShare團隊
php


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

StatusBar

打算作DarkMode適配的開發者須要注意使用的statusBar的類型。ios

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

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

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

不一樣類型的狀態欄在亮、暗模式下的相關示意圖以下:xcode

qiLightStatusBar1.png

qiLightStatusBar2.png

qiLightStatusBar3.png

qiDarkStatusBar11.png

qiDarkStatusBar22.png

qiDarkStatusBar33.png

示例代碼bash

- (UIStatusBarStyle)preferredStatusBarStyle {
    
    return UIStatusBarStyleDefault;
}
複製代碼

更多狀態欄顯示樣式的內容,你們能夠查看dac_1033關於iOS 狀態欄、導航欄的幾處筆記微信

UIActivityView

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

推薦開發者使用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

參考學習網址


瞭解更多iOS及相關新技術,請關注咱們的公衆號:

小編微信:可加並拉入《QiShare技術交流羣》。

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)

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

相關文章
相關標籤/搜索