iOS13出来已经挺久了,今天才认真的看了看深色模式的魅力,老工程适配深色模式的确会是个庞大的工程,这篇文章记录一下,今天下午简单做了些适配深色模式的功课。
1. 颜色适配
在iOS13中系统提供了动态颜色的方法:
+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
我们可以直接封装一个UIColor的类别来获取不同模式下的颜色:
+(UIColor *)colorWithDarkModeColor:(UIColor *)darkColor normalColor:(UIColor *)color
{
if (@available(iOS 13.0,*)) {
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleDark) {
return darkColor;
}
else {
return color;
}
}];
return dyColor;
}
return color;
}
这样,我们在使用的时候就可以方便的调用,当模式改变后,系统会自己根据是否是深色模式更改不同的颜色:
UIColor *color = [UIColor colorWithDarkModeColor:[UIColor blackColor] normalColor:[UIColor whiteColor]];
[self.view setBackgroundColor:color];
如果遇到一些比较特殊的情况,那我们就需要监听用户模式的改变,这个方法在UIViewController和UIView中都可以直接调用:
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection API_AVAILABLE(ios(8.0));
///Example
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
NSLog(@"-----current-%ld\n=====previous=%ld",self.traitCollection.userInterfaceStyle,previousTraitCollection.userInterfaceStyle);
// trait发生了改变
if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
}
}
2. 图片适配
在Asset里面,Xcode在Appearance里可以选择不同的模式,一般情况下我们只用适配深色模式和非深色模式,如图:
然后代码里就直接写:
imgView.image=[UIImage imageNamed:@"iconImage"];
这点,很符合苹果的个性,就是这么随意,改变模式后自动更改图片,开发者不用再做其他的事情。
也许很多开发者会发现,大厂的应用,所有的图标都很简单,线性,单色等特点,有抖音的可以看下抖音的图标(点赞、评论、分享、查找...),看过后相信有人会直接想到iconfont这个东西,没错,如果你们的应用之前考虑过瘦身,应该看到过使用iconfont来瘦身的文章。举个例子下面这些图标:
如果是png格式的话,最起码需要
50kb
空间,再加上适配深色模式double一下就是
100kb
!那么如果用iconfont的话,大小之后
2kb
,而且可以随便改尺寸。整整
50
倍,什么概念。用了iconfont的话在适配深色模式的时候也会比较简单,就像颜色适配一样的容易,最后动图中的下面3个图标都是用的iconfont。
label.font = [UIFont imageFontWithSize:34.0];
label.text = @"\U0000e668";
label.textColor=[UIColor colorWithDarkModeColor:[UIColor lightGrayColor] normalColor:[UIColor redColor]];
里面用到了一个UIFont的类别方便加载iconfont:
+(UIFont *)imageFontWithSize:(CGFloat)fontSize
{
return [UIFont fontWithName:@"iconFont" size: fontSize];
}
简单做了个小小Demo放在了GitHub-iOS深色模式
上,效果图如下: