笔者最近看了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(一)
奇舞周刊