iOS13 黑暗模式

參考原文

  • 一案训、適配Dark Mode
    顏色適配
    圖片適配
  • 二斤程、獲取當(dāng)前模式(Light or Dark)
  • 三、其他內(nèi)容
  • 四专筷、總結(jié)

一、適配Dark Mode

1 顏色適配

  • iOS13 之前 UIColor只能表示一種顏色蒸苇,而從 iOS13 開始UIColor是一個(gè)動(dòng)態(tài)的顏色磷蛹,在Light ModeDark Mode可以分別設(shè)置不同的顏色。
  • iOS13系統(tǒng)提供了一些動(dòng)態(tài)顏色
) UIColor *systemBrownColor        API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemIndigoColor       API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemGray2Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray3Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray4Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray5Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray6Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *labelColor              API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *secondaryLabelColor     API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *tertiaryLabelColor      API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *quaternaryLabelColor    API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *linkColor               API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *placeholderTextColor    API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *separatorColor          API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *opaqueSeparatorColor    API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemBackgroundColor                   API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *secondarySystemBackgroundColor          API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *tertiarySystemBackgroundColor           API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGroupedBackgroundColor            API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *secondarySystemGroupedBackgroundColor   API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *tertiarySystemGroupedBackgroundColor    API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemFillColor                         API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *secondarySystemFillColor                API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *tertiarySystemFillColor                 API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *quaternarySystemFillColor               API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);

① 實(shí)例

[self.view setBackgroundColor:[UIColor systemBackgroundColor]];
[self.titleLabel setTextColor:[UIColor labelColor]];
[self.detailLabel setTextColor:[UIColor placeholderTextColor]];

系統(tǒng)UIColor樣式
用法和iOS13之前的一樣溪烤,使用系統(tǒng)提供的這些動(dòng)態(tài)顏色味咳,不需要其他的適配操作

② 自定義動(dòng)態(tài)UIColor

在實(shí)際開發(fā)過程,系統(tǒng)提供的這些顏色還遠(yuǎn)遠(yuǎn)不夠檬嘀,因此我們需要?jiǎng)?chuàng)建更多的動(dòng)態(tài)顏色
初始化動(dòng)態(tài)UIColor方法
iOS13 UIColor增加了兩個(gè)初始化方法槽驶,使用以下方法可以創(chuàng)建動(dòng)態(tài)UIColor
注:一個(gè)是類方法,一個(gè)是實(shí)例方法

+ (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);

這兩個(gè)方法要求傳一個(gè)block進(jìn)去
當(dāng)系統(tǒng)在LightMode和DarkMode之間相互切換時(shí)就會(huì)觸發(fā)此回調(diào)
這個(gè)block會(huì)返回一個(gè)UITraitCollection類
我們需要使用其屬性userInterfaceStyle鸳兽,它是一個(gè)枚舉類型掂铐,會(huì)告訴我們當(dāng)前是LightMode還是DarkMode

typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
    UIUserInterfaceStyleUnspecified,
    UIUserInterfaceStyleLight,
    UIUserInterfaceStyleDark,
} API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);

實(shí)例

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

2.圖片適配

  • 打開Assets.xcassets
  • 新建一個(gè)Image set
  • 打開右側(cè)工具欄,點(diǎn)擊最后一欄揍异,找到Appearances全陨,選擇Any,Dark
  • 將兩種模式下不同的圖片資源都拖進(jìn)去
  • 使用該圖片

3.獲取當(dāng)前模式(Light or Dark)

有時(shí)候我們需要知道當(dāng)前處于什么模式蒿秦,并根據(jù)不同的模式執(zhí)行不同的操作
iOS13中CGColor依然只能表示單一的顏色
通過調(diào)用UITraitCollection.currentTraitCollection.userInterfaceStyle
獲取當(dāng)前模式

實(shí)例

if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
        [self.titleLabel setText:@"DarkMode"];
    }
    else {
        [self.titleLabel setText:@"LightMode"];
    }
}

其他

1.監(jiān)聽模式切換

有時(shí)我們需要監(jiān)聽系統(tǒng)模式的變化烤镐,并作出響應(yīng)
那么我們就需要在需要監(jiān)聽的viewController中蛋济,重寫下列函數(shù)

// 注意:參數(shù)為變化前的traitCollection
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection;
 
// 判斷兩個(gè)UITraitCollection對象是否不同
- (BOOL)hasDifferentColorAppearanceComparedToTraitCollection:(UITraitCollection *)traitCollection;

① 示例

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    // trait發(fā)生了改變
    if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
    // 執(zhí)行操作
    }
    }

2.CGColor適配

我們知道iOS13后棍鳖,UIColor能夠表示動(dòng)態(tài)顏色,但是CGColor依然只能表示一種顏色碗旅,那么對于CALayer等對象如何適配暗黑模式呢?當(dāng)然是利用上一節(jié)提到的監(jiān)聽模式切換的方法啦渡处。


- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
        if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
            return [UIColor redColor];
        }
        else {
            return [UIColor greenColor];
        }
    }];
        layer.backgroundColor = dyColor.CGColor;
}

??!!! 設(shè)置layer顏色都是在traitCollectionDidChange中,意味著如果沒有發(fā)生模式切換祟辟,layer將會(huì)沒有顏色医瘫,需要設(shè)置一個(gè)基本顏色

3.模式切換時(shí)打印log

模式切換時(shí)自動(dòng)打印log,就不需要我們一次又一次的執(zhí)行po命令了

  • 在Xcode菜單欄Product->Scheme->Edit Scheme
  • 選擇Run->Arguments->Arguments Passed On Launch
  • 添加以下命令即可
    -UITraitCollectionChangeLoggingEnabled YES

4.強(qiáng)行設(shè)置App模式

當(dāng)系統(tǒng)設(shè)置為Light Mode時(shí)旧困,對某些App的個(gè)別頁面希望一直顯示Dark Mode下的樣式醇份,這個(gè)時(shí)候就需要強(qiáng)行設(shè)置當(dāng)前ViewController的模式了

// 設(shè)置當(dāng)前view或viewCongtroller的模式
@property(nonatomic) UIUserInterfaceStyle overrideUserInterfaceStyle;

示例

// 設(shè)置為Dark Mode即可
[self setOverrideUserInterfaceStyle:UIUserInterfaceStyleDark];

?? 注意!!!

當(dāng)我們強(qiáng)行設(shè)置當(dāng)前viewController為Dark Mode后稼锅,這個(gè)viewController下的view都是Dark Mode
由這個(gè)ViewController present出的ViewController不會(huì)受到影響,依然跟隨系統(tǒng)的模式
要想一鍵設(shè)置App下所有的ViewController都是Dark Mode僚纷,請直接在Window上執(zhí)行overrideUserInterfaceStyle
對window.rootViewController強(qiáng)行設(shè)置Dark Mode也不會(huì)影響后續(xù)present出的ViewController的模式

5.NSAttributedString優(yōu)化

對于UILabel矩距、UITextField、UITextView怖竭,在設(shè)置NSAttributedString時(shí)也要考慮適配Dark Mode锥债,否則在切換模式時(shí)會(huì)與背景色融合,造成不好的體驗(yàn)

不建議的做法
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:16]};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"富文本文案" attributes:dic];
推薦的做法
// 添加一個(gè)NSForegroundColorAttributeName屬性
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor labelColor]};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"富文本文案" attributes:dic]

總結(jié)

總的來說痊臭,iOS13主要有以下變化:
1.支持 Dark Mode
2.UIColor變?yōu)閯?dòng)態(tài)顏色
3.更新StatusBar樣式
4.更新UIActivityIndicatorView樣式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哮肚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子广匙,更是在濱河造成了極大的恐慌允趟,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艇潭,死亡現(xiàn)場離奇詭異拼窥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蹋凝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門鲁纠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鳍寂,你說我怎么就攤上這事改含。” “怎么了迄汛?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵捍壤,是天一觀的道長。 經(jīng)常有香客問我鞍爱,道長鹃觉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任睹逃,我火速辦了婚禮盗扇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沉填。我一直安慰自己疗隶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布翼闹。 她就那樣靜靜地躺著斑鼻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪猎荠。 梳的紋絲不亂的頭發(fā)上坚弱,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天蜀备,我揣著相機(jī)與錄音,去河邊找鬼荒叶。 笑死琼掠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的停撞。 我是一名探鬼主播瓷蛙,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼戈毒!你這毒婦竟也來了艰猬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤埋市,失蹤者是張志新(化名)和其女友劉穎冠桃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體道宅,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡食听,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了污茵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片樱报。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖泞当,靈堂內(nèi)的尸體忽然破棺而出迹蛤,到底是詐尸還是另有隱情,我是刑警寧澤襟士,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布盗飒,位于F島的核電站,受9級(jí)特大地震影響陋桂,放射性物質(zhì)發(fā)生泄漏逆趣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一嗜历、第九天 我趴在偏房一處隱蔽的房頂上張望宣渗。 院中可真熱鬧,春花似錦秸脱、人聲如沸落包。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涯鲁,卻和暖如春巷查,著一層夾襖步出監(jiān)牢的瞬間有序,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工岛请, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旭寿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓崇败,卻偏偏與公主長得像盅称,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子后室,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 原文博客地址: iOS13適配深色模式(Dark Mode) 好像大概也許是一年前, Mac OS系統(tǒng)發(fā)布了深色模...
    TitanCoder閱讀 37,007評論 8 61
  • iOS13適配簡介 iOS 13系統(tǒng)開發(fā)者版本已經(jīng)公布缩膝,公測版本會(huì)在7月份放出,正式版本會(huì)在9月份更新岸霹,9月份的正...
    四月的風(fēng)_3cec閱讀 3,446評論 1 0
  • “主公不必憂慮疾层,憑我手上長刀,鞍下雕弓贡避,一千個(gè)來痛黎,一千個(gè)死。擊鼓吧刮吧,大人拭目以待湖饱,看我刀斬那關(guān)羽∩蹦恚” “黃忠琉历,黃忠...
    玖思閱讀 3,968評論 1 7
  • 今天真是高興。兒子下午放學(xué)回到家水醋,主動(dòng)要求先吃飯旗笔,我以為是老公做的豬腳好吃,也以為是他長身體知道餓了拄踪。吃完飯蝇恶,兒子...
    嚕小嚕閱讀 165評論 0 0