筆者最近看了DarkMode相關的內容。本文將會講解亮/暗模式切換時statusBar(狀態欄)、UIActivityIndicatorView(活動指示器視圖)、文字繪製顏色及設置layer,border顏色、UIVisualEffectView。html
打算作DarkMode適配的開發者須要注意使用的statusBar的類型。ios
使用UIStatusBarStyleLightContent類型statusBar的開發者須要注意Light模式下,狀態欄部分的內容是沒法看清的。git
接下來想使用UIStatusBarStyleDarkContent類型statusBar的開發者須要注意Dark模式下,狀態欄部分的內容是沒法看清的。github
除了咱們想要App或某些界面只能支持DarkMode或者支持LightMode的狀況,咱們要使用UIStatusBarStyleDefault類型的statusBar。web
不一樣類型的狀態欄在亮、暗模式下的相關示意圖以下:xcode
示例代碼bash
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
複製代碼
更多狀態欄顯示樣式的內容,你們能夠查看dac_1033的關於iOS 狀態欄、導航欄的幾處筆記微信
使用UIActivityIndicatorView的UIActivityIndicatorViewStyleWhiteLarge的開發者須要注意,UIActivityIndicatorViewStyleWhiteLarge樣式的UIActivityIndicatorView沒法在DarkMode模式下基本看不見。其中MBProgressHUD使用過UIActivityIndicatorView,不過由於MBProgressHUD在外側嵌套了一層黑色容器視圖,因此在Dark模式下運行效果尚可。app
推薦開發者使用UIActivityIndicatorViewStyleLarge或UIActivityIndicatorViewStyleMedium類型的UIActivityIndicatorView。
相關示意圖以下,可看出只有中間的UIActivityIndicatorViewStyleLarge類型的UIActivityIndicatorView能夠再亮、暗模式下均能正常使用,固然開發者也能夠選擇去改變UIActivityIndicatorView的tintColor來適配DarkMode。
示例代碼
UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
複製代碼
若是咱們使用drawRect繪製屬性字符串時,沒有指定顏色,系統會默認爲文字顏色爲黑色。或者以前咱們設置的是較暗的一個顏色。相關狀況在Dark模式下,相應文字基本會看不清楚。
示意圖以下:
那麼爲了繪製的文字在切換亮/暗模式的時候能夠正常顯示,咱們須要指定繪製的文字的顏色。好比明確設置
textAttris[NSForegroundColorAttributeName] = [UIColor labelColor];
複製代碼
由於指定字符串屬性字典的方式不一樣,當建立字符串的屬性字典的時候,你們可能會遇到以下的一個問題。
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的部分,如設置Layer顏色,border顏色。設置Layer顏色會發如今亮、暗模式切換的時候,不能順利地得以切換,能夠在適當的時機進行顏色設置,筆者認爲能夠在traitCollectionDidChange的時候多設置一次相應的顏色以免某些切換不流暢現象。
相關示意圖以下。
截圖中的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,筆者瞭解得比較少,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.
示例代碼:
// 建立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;
複製代碼
固定亮模式:設置info.plist文件中的User Interface Style爲"Light"
固定暗模式:設置info.plist文件中的User Interface Style爲"Dark"
方式:相應控制器重寫overrideUserInterfaceStyle。
固定亮模式:
- (UIUserInterfaceStyle)overrideUserInterfaceStyle {
return UIUserInterfaceStyleLight;
}
複製代碼
固定暗模式:
- (UIUserInterfaceStyle)overrideUserInterfaceStyle {
return UIUserInterfaceStyleDark;
}
複製代碼
詳情見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(一)
奇舞週刊