ios 暗黑模式 Dark Mode

*ios 暗黑模式 Dark Mode

一、UITraitCollection
为表征 size class 而生,用来区分设备。你可以在它身上获取到足以区分所有设备的特征

API:
(1)判断当前设备时 iPhone/iPad/tv/carPlay 的配置

+ (UITraitCollection *)traitCollectionWithLayoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection API_AVAILABLE(ios(10.0));
@property (nonatomic, readonly) UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); // unspecified: UITraitEnvironmentLayoutDirectionUnspecified

(2)图片 Scale 的配置

+ (UITraitCollection *)traitCollectionWithForceTouchCapability:(UIForceTouchCapability)capability API_AVAILABLE(ios(9.0));
@property (nonatomic, readonly) UIForceTouchCapability forceTouchCapability API_AVAILABLE(ios(9.0)); // unspecified: UIForceTouchCapabilityUnknown

(3)全局字体大小的配置

+ (UITraitCollection *)traitCollectionWithPreferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory API_AVAILABLE(ios(10.0));
@property (nonatomic, copy, readonly) UIContentSizeCategory preferredContentSizeCategory API_AVAILABLE(ios(10.0)); // unspecified: UIContentSizeCategoryUnspecified

(4)色域的配置

+ (UITraitCollection *)traitCollectionWithDisplayGamut:(UIDisplayGamut)displayGamut API_AVAILABLE(ios(10.0));
@property (nonatomic, readonly) UIDisplayGamut displayGamut API_AVAILABLE(ios(10.0)); // unspecified: UIDisplayGamutUnspecified

(5)是否开启高对比度的配置

+ (UITraitCollection *)traitCollectionWithAccessibilityContrast:(UIAccessibilityContrast)accessibilityContrast API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (nonatomic, readonly) UIAccessibilityContrast accessibilityContrast API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos); // unspecified: UIAccessibilityContrastUnspecified

(6)全局字重的配置

+ (UITraitCollection *)traitCollectionWithLegibilityWeight:(UILegibilityWeight)legibilityWeight API_AVAILABLE(ios(13.0), tvos(13.0), watchos(6.0));
@property (nonatomic, readonly) UILegibilityWeight legibilityWeight API_AVAILABLE(ios(13.0), tvos(13.0), watchos(6.0)); // unspecified: UILegibilityWeightUnspecified

(7)主题的配置

+ (UITraitCollection *)traitCollectionWithUserInterfaceStyle:(UIUserInterfaceStyle)userInterfaceStyle API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);
@property (nonatomic, readonly) UIUserInterfaceStyle userInterfaceStyle API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos); // unspecified: UIUserInterfaceStyleUnspecified

2、如何获取 UITraitCollection
UITraitCollection有UITraitEnvironment 协议,UIKit 中大多数 UI 的基础类 (包括 UIScreen,UIWindow,UIViewController 和 UIView) 都实现了 UITraitEnvironment 这个协议,遵循了这个协议,用来监听和设置 traitCollection 的变化。UITraitCollection本身是一个配置的集合,每个 UIView/UIViewController都有自己的 UITraitCollection对象,并将自己的UITraitCollection传递给子UIView/UIViewController作为默认值。
(1)可以通过 UIView/UIViewController的属性 traitCollection 获取到当前视图的 UITraitCollection 对象

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITraitCollection *traitCollection = self.traitCollection;
}

(2)可以通过子类重写如下方法的方式监控 traitCollection 属性的变化

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
}

(3)获取全局的UITraitCollection

[UITraitCollection currentTraitCollection]

二、overrideUserInterfaceStyle属性

在iOS13,为UIViewController和UIView扩展了一个新的API-overrideUserInterfaceStyle,是一个枚举类型


typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
    UIUserInterfaceStyleUnspecified, /// 跟随系统主题
    UIUserInterfaceStyleLight, /// 浅色模式
    UIUserInterfaceStyleDark, /// 深色模式
} API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);

使用方法,官方文档大致是这么说的:

*通过设置overrideUserInterfaceStyle属性以使该视图及其子视图具有特定的UIUserInterfaceStyle。但如果想要获取当前的UIUserInterfaceStyle,需要改用traitCollection.userInterfaceStyle。

尽可能使用UIViewController上的overrideUserInterfaceStyle属性。仅在以下时间使用此属性:

在单个视图或小视图层次结构上局部使用特定样式。
您希望在整个UIWindow及其视图控制器和模态弹出的ViewController上使用特定样式,且不希望强制更改整个应用程序具有样式。 (如果您确实希望整个应用程序具有某种样式,请不要使用它,而是在Info.plist中设置UIUserInterfaceStyle键。)
当设置在普通的UIView上时:
此属性仅影响此视图及其子视图的特征。
它不会影响任何视图控制器或其他视图控制器的子视图。
在UIWindow上设置时:
此属性会影响rootViewController,从而影响整个视图控制器和视图层次结构。
它还会影响该window模态出来的界面。

需要改变当前视图模式时,在UIView或者UIViewController设置self.overrideUserInterfaceStyle = UIUserInterfaceStyleDark即可。

注意:overrideUserInterfaceStyle默认是UIUserInterfaceStyleUnspecified,当指定overrideUserInterfaceStyle为UIUserInterfaceStyleLight或者UIUserInterfaceStyleDark时,通过self.traitCollection.userInterfaceStyle获取到的值也为设置后的overrideUserInterfaceStyle值

三、如何监听模式变化(暗黑模式和浅色模式)
(1)我们可以在 UIViewController 或 UIView 中调用 traitCollection.userInterfaceStyle 来获取当前视图的样式,代码如下

if trainCollection.userInterfaceStyle == .dark {
    // Dark
} else {
    // Light
}

(2)还可以通过 UITraitCollection.current 这个属性来获取当前 App 的颜色模式。但是并不是所有的时候获取的都是正确的,只有在下面这些方法中,才可以放心的使用这个属性

在这里插入图片描述

(3)系统为我们提供了一个回调方法,当 light dark 切换时就会触发这个方法。

/*! To be overridden as needed to provide custom behavior when the environment's traits change. */
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection API_AVAILABLE(ios(8.0));

使用举例:

- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {
    [super traitCollectionDidChange: previousTraitCollection];
    if ((self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass)
        || (self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass)) {
        // your custom implementation here
        NSLog(@"traitCollectionDidChange");
    }
}

四、改变当前模式

当我们设置一个 controller 为 dark 之后,这个 controller 下的 view,都会是 dark mode,但是后续推出的 controller 仍然是跟随系统的样式。
因为苹果对 overrideUserInterfaceStyle 属性的解释是这样的。
当我们在一个普通的 controlle, view 上重写这个属性,只会影响当前的视图,不会影响前面的 controller 和后续推出的 controller。
但是当我们在 window.rootViewController 上设置 overrideUserInterfaceStyle 的时候,就会影响 rootViewController 下所有的 controller, view,包括后续推出的 controller,所以,如果 App 打开夜间模式,那么很简单我们只需要设置 rootViewController 的 overrideUserInterfaceStyle 属性就好了。

    if (@available(iOS 13.0, *)) { /// 使用浅色模式
        self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
    }

五、全局禁用暗黑模式
配置plist文件: 在Info.plist 文件中,添加UIUserInterfaceStyle key 名字为 User Interface Style 值为String,将UIUserInterfaceStyle key 的值设置为 Light

如何获取当前模式 (Light or Dark)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值