DarkMode适配(iOS)

本来几个月前就应该更新这篇iOS 13的DarkMode文章的…然而发现放到了某个未命名的.md文件里头去了…哈哈,整理一下重新发一下

首先,我看到好多朋友在群里问,为什么用新编译器(Xcode 11)后开了darkmode之后开启darkmode.[UIColor whiteColor]这种设置颜色之后会变成黑的.这是因为iOS 13(Xcode 11及以上)的UIColor变成了dynamic的.

不适配黑暗模式解决方法

  • 1.使用低于Xcode 11的Xcode版本.
  • 2.不要使用"动态"的颜色.推荐使用手动创建的rgb色.
  • 3.在info.plist中添加key:UIUserInterfaceStyle.value为String类型的Light
  • 4.在UIViewController中设置self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight.记得判断一下版本.

适配黑暗模式的情况

首先,我们看下和darkmode有关的枚举

UIUserInterfaceStyle

typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
	///  未确认
    UIUserInterfaceStyleUnspecified,
    /// 亮色模式
    UIUserInterfaceStyleLight,
    /// 黑暗模式
    UIUserInterfaceStyleDark,
} API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);

注意的是iOS 13以上,所有系统提供的color都变成了dynamiccolor.也就是说,.light的情况下和.dark的情况下的表现的颜色是不一样的.然而,cgcolor还是非动态的.

UIColor的适配

代码方式
UIColor *dynamicColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
    switch (traitCollection.userInterfaceStyle) {
        case UIUserInterfaceStyleLight: {/// 亮色模式颜色
            return [UIColor whiteColor];
        }
            break;
        case UIUserInterfaceStyleDark: {/// 暗色模式颜色
            return [UIColor whiteColor];
        }
            break;
        default: {
            return [UIColor whiteColor];
        }
            break;
    }
}];

注意的是.如果颜色没有被使用.这个block就不会有回调.

Asset.xcassets方式

创建Color Set

DarkMode适配(iOS)_第1张图片

DarkMode适配(iOS)_第2张图片

使用也比较简单

[UIColor colorNamed:@"assetname"];

UIImage的适配

UIImage *image = [UIImage new];
[image.imageAsset registerImage:[UIImage imageNamed:@"1"] withConfiguration:[[UIImageConfiguration alloc] configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]];
[image.imageAsset registerImage:[UIImage imageNamed:@"2"] withConfiguration:[[UIImageConfiguration alloc] configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]]];
self.imageView.image = image;
Asset.xcassets方式

DarkMode适配(iOS)_第3张图片

DarkMode的补充说明

UITraitCollection直接翻译就是UI有关的特性集合.像是Darkmode切换、当前设备是哪个os的之类的.我们就是需要其中的userInterfaceStyle属性.

直接获取当前的userInterfaceStyle

UITraitCollection *traitCollection = [UITraitCollection currentTraitCollection];
switch (traitCollection.userInterfaceStyle) {
	case UIUserInterfaceStyleUnspecified:
		break;
	case UIUserInterfaceStyleLight:
		break;
	case UIUserInterfaceStyleDark:
		break;
	default:
		break;
}

通过UIView与UIViewController获取改变后的状态

/// 因为UIView以及UIViewController都实现了如下的代理,可以通过如下代理获取UITraitCollection的改变后的状态.
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection

补充

强制设置某个View或者VC的显示模式

self.overrideUserInterfaceStyle =  UIUserInterfaceStyleDark;

强制设置所有View、VC的显示模式

ps:设置window的rootVC也是和上面的设置一样只会影响当前VC.modal出来其他的还是不会改变.如果设置window的属性的话.就会改变所有的了

((SceneDelegate *)[UIApplication sharedApplication].connectedScenes.anyObject.delegate).window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;

或是把info.plist中的UIApplicationSceneManifest删掉.使用下面的"老代码".

[UIApplication sharedApplication].delegate.window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;

你可能感兴趣的:(iOS)