阅读 1482

WWDC2019-214-iOS 13 适配 dark mode

Dark Mode

参考链接:

WWDC 2019-Implementing Dark Mode on iOS

Reource-Adopting iOS Dark Mode

一 、原理

状态UITraitCollection改变从屏幕到 view 的传递过程,目前支持手动触发和自动触发。如果设置了 view 的 dynamic color 和 dynamic image, 则 view 的 color 和 image 都会跟着改变。

condition_change

当前情景改变会调用UITraitEnvironment(iOS 8)协议的方法,对于需要单独适配的 View,ViewController 需要在此方法进行一些特殊处理,UIView,UIViewController 均遵守该协议

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    
    // 对比情景改变
    BOOL isChanged = [traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection];
}
复制代码

View 的 layoutSubView, ViewController 的 viewDidLayoutSubviews 均会触发 traitCollectionDidChange:方法

current_trait_collection

二 、适配相关

  1. Dynamic Color

    动态颜色,根据当前情景自动切换颜色,iOS 13 新定义了一批 dynamic color, 大部分以 system 开头,也有以适用类别开头的,例如 labelColor,systemGroupedBackgroundColor,可以直接用

    • 自定义 dynamic color

      // iOS 13
      UIColor *dynamicColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitC) {
              if (traitC.userInterfaceStyle == UIUserInterfaceStyleDark) {
                  return UIColor.redColor;
              } else {
                  return UIColor.greenColor;
              }
          }];
      复制代码
    • 根据当前情景取出 dynamic color 中的色值----用于根据不同情景取色值,设置色值。

      UIColor *dynamicColor = [UIColor systemBackgroundColor];
      UITraitCollection *traitCollection = someView.traitCollection;
      UIColor *resolvedColor = [dynamicColor resolvedColorWithTraitCollection:traitCollection];
      复制代码

      示例用途:

      		// 设置 view 的 border 颜色
      		UILayer *layer = [UILayer new];
      
      		UITraitCollection *traitCollection = someView.traitCollection;
      
      		// option 1 -- iOS 8
      		UIColor *resolvedColor = [dynamicColor resolvedColorWithTraitCollection:traitCollection];
      		layer.borderColor = resolvedColor.CGColor;
      
          // option 2 -- iOS 13
          [traitCollection performAsCurrentTraitCollection:^{
              layer.borderColor = resolvedColor.CGColor;
          }];
          
          // option 3 -- iOS 13
          UITraitCollection *savedTraitCollection = [UITraitCollection currentTraitCollection];
          
          [UITraitCollection setCurrentTraitCollection:traitCollection];
          layer.borderColor = UIColor.labelColor.CGColor;
          
          [UITraitCollection setCurrentTraitCollection:savedTraitCollection];
      复制代码
  2. Dynamic Image

    • 创建 dynamic image

      dynamic_image

  3. webContent

    • Use color-scheme to declare support
    • Adopt prefers-color-scheme media query
    • Use for hero graphics
    • Consider using var() for color schemes

前端代码示例:详见 WWDC Resource

// 色值
:root {
  color-scheme: light dark; 
  --post-title-color: #333;
  --header-bg-color: #593a78;
  --header-txt-color: white;
}

@media (prefers-color-scheme: dark) {
  :root {
  --post-title-color: white;
  --header-bg-color: #513d66;
  --header-txt-color: #eee;
  }
}

h1 {
color: var(--post-title-color);
}
.header {
background-color: var(--header-bg-color);
color: var(--header-txt-color);
}

// 图片
<img src="mojave-day.jpg">

<picture>
  <source srcset="mojave-night.jpg" media="(prefers-color-scheme: dark)">
  <img src="mojave-day.jpg">
</picture>

复制代码

三、调试

设置启动参数 Enable debug logging with launch argument

-UITraitCollectionChangeLoggingEnabled YES

关注下面的标签,发现更多相似文章
评论