iOS13 黑暗模式

Any Appearance :
Use the Any Appearance variant to specify the color value to use on older systems that do not support Dark Mode. 为了适配不支持黑暗模式的系统版本
Light Appearance : 白色模式
Dark Appearance : 黑色模式

颜色

方案一
通过Assets catalog,指定各种模式下颜色的设定。
20190620091125

//改方法会从主功能的Assets.xcassets根据当前环境(DarkMode,LightMode)获取Color对应的颜色
let aColor = UIColor(named: "Color")
//该方法会从指定bundle中的.xcassets文件中获取颜色,traitCollection为当前的特征集合,其中包含了当前的颜色模式。
let color = UIColor(named: "Color", in: Bundle.currentBundle, compatibleWith: traitCollection)

图片

方案一
通过Assets catalog,指定各种模式下颜色的设定。
与颜色的配置一致
20190620095918

//该方法会从主功能的Assets.xcassets根据当前环境(DarkMode,LightMode)获取Color对应的颜色
let anImage = UIImage(named: "Image")
//该方法会从指定bundle中的.xcassets文件中获取图片,traitCollection为当前的特征集合,其中包含了当前的颜色模式。
let anImage = UIImage(named: "Image", in: Bundle.currentBundle, compatibleWith: traitCollection)

方案二:(iOS13 Only)
Symbol Images是基于矢量的图片格式

有以下优点:

  • 缩放时不会产生失真
  • 可以自行进行染色
  • 具有baseline信息,可以以文字的形式出现。
  • 可以用字体相关样式信息配置,使它们看起来好像他们属于该字体。

Symbol Images相关配置文档

渲染

以上方式可以解决大部分问题。但是某些情况下满足不了需求,比如通过drawRect:绘制的视图,CALayer的相关配置。不用担心,你想到的苹果都想到了。下面列出了,当视图模式(UIUserInterfaceStyle)变化时回调的方法。override这些方法,进行对应环境的适配即可。获取当前模式 可以通过 self.traitCollection.userInterfaceStyle获取即可。

  • UIView
    -traitCollectionDidChange:
    -layoutSubviews
    -drawRect:
    -updateConstraints
    -tintColorDidChange

  • UIViewController
    -traitCollectionDidChange:
    -updateViewConstraints
    -viewWillLayoutSubviews
    -viewDidLayoutSubviews

  • UIPresentationController
    -traitCollectionDidChange:
    -containerViewWillLayoutSubviews
    -containerViewDidLayoutSubviews

补充说明:
traitCollection 是在 UITraitEnvironment 协议中的属性。该属性由UIScreen,UIWindow,UIView,UIViewController,UIPresentationController实现。
traitCollection属性包含许多交互界面相关环境的配置,DarkMode就属于他的一部分(UIUserInterfaceStyle)。其他配置不在本文讨论。
UIUserInterfaceStyle包含light、dark、unspecified

Asset catalog打包

那么问题来了,想把Assets catalog 打包进framework怎么办?通常我们想在framework中打包资源一般会把所有资源文件先打包成Bundle文件,再把Bundle文件放到framework中。你可能会把.xcassets文件直接放进Bundle文件里。这样当然是不行的。
你可以新建一个iOS项目进行build,然后查看build日志,可以看到如下日志:
20190620142108
XCode会将.xcassets进行编译,具体怎么编译,还没深入研究。
XCode不止编译代码,还会编译一些资源,如xib,coredata相关等等。但是Bundle文件不会进行编译。所以直接将.xcassets 放入Bundle文件中是不会参与编译的。那怎么办?

很简单!

  1. 在framework工程中建立Bundle的target,注意是target不是Bundle文件。
  2. 将.xcassets放到这个新建的target中。
  3. 为framework的target添加bundle依赖。

搞定!

以下是具体步骤:

  1. 点我下载xcode插件
  2. 在终端执行以下命令:

    cd ~/Downloads
    unzip iOS_bundle_template.zip
    mkdir -p ~/Library/Developer/Xcode/Templates/Custom
    mv "iOS Resources Bundle.xctemplate" ~/Library/Developer/Xcode/Templates/Custom
  3. 新建Bundle target
    20190620143733

  4. 为Test添加TestBundle依赖
    20190620143901

  5. build 一下 framework 你会发现 Products文件夹下回出现TestBundle文件。
    20190620144442

  6. 进入文件夹看看.xcassets文件编译成什么了
    20190620144616
    原来.xcassets编译成了.car

  7. 使用资源

    //将TestBundle 传入 即可
    let anImage = UIImage(named: "Image", in: TestBundle, compatibleWith: traitCollection)
    

搞定!!

Demo在这里
参考文献:

Unleashing the power of asset catalogs and bundles on iOS
Apple Develop document

You Might Also Like
发表评论