• 【iOS】iOS13新增的暗黑模式(Dark Mode)


    在iOS13中,苹果推出了新的暗黑模式,这就帮助我们在黑夜中使用不那么刺眼的应用。这个还是很符合大多数人在夜间玩手机的习惯。既然这样,那我们作为一个合格的开发,当然要及时拥抱变化,早日跟进这个功能。

        DarkMode中有哪些适配方案呢?
        1.将两种主题不同的素材直接存储在对象中,UIKit在主题变化时获取对应的素材进行更新展示。(例子:在Assets中设置不同的模式下的颜色和图片)
        优点:工作量少,对原代码影响较少,开发省时省力
        缺点:灵活性较差,如果是不同图的话会对包的体积有一定影响
        2.通过接受主题变化的通知,在通知回调中做相应的适配工作
        优点:高度自定义,灵活性强
        缺点:代码量相对较多,适配工作量较大
    

    下面分别对两种不同的放进行举例:
    第一种方案:
    1.1 颜色的处理
    1.1.1 使用系统提供的UIKit的颜色(如labelColor、UIColor.secondaryLabelColor等)。这些颜色都内置了适配颜色,会根据不同主题自定切换适配。

          if (@available(iOS 13.0, *)) {
                _textLabel.textColor  = UIColor.secondaryLabelColor;
          }else {
                _textLabel.textColor = [UIColor redColor];
          }
    

    1.1.2 创建动态颜色
    通过对UIColor新增扩展类的方式添加一个方法,在设置时添加lightcolor和darkcolor。
    之前还考虑过通过设置宏定义进行自动切换,只要在颜色的宏中修改就行,但是由于xcode没有检测到校验 回报多处警告,影响代码视觉体验,所以改为扩展。

    #define kDarkMode @available(iOS 13.0, *) && UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark
    #define Color_Background        kDarkMode?[UIColor blackColor]:[UIColor whiteColor]
    

    缺点:操作量较大

    1.1.3 在assets中添加动态颜色资源


    步骤二可以只设置any和dark 也可以设置any、light和dark

    // 通过name方式直接取
    UIColor *backgroundColor = [UIColor colorNamed:@"backgroundColor"];
    

    1.2 图片的适配
    1.2.1 在assets中添加动态图片资源

    类似于颜色设置,使用方法还是和之前一样。
    1.2.2 创建自己的动态图片
    通过对UIImage新增扩展类的方式添加一个方法,在设置时添加lightcolor和darkcolor。类似于动态颜色的设置
    1.2.3 网络图片
    比如有这么一种场景:我浅色主题和深色主题下显示不同的图片,并且两张图片都不是本地的,都是从网络获取,实现思路大概是:先把两张图片下下来,在本地组装成动态图片
    这个不常见,一般来说都是显示同一张图片。我们也可以通过sdwebimage进行设置。下载完图片后进行动态整合。

    2.1 UITraitCollection
    UITraitCollection是用来处理苹果手机的一些特性的存储和UI相关的配置 比如我修改了某些系统设置,如:改字体大小

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

    关于主题模式切换的属性是我们本节关注的重点:

    typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
        UIUserInterfaceStyleUnspecified,
        UIUserInterfaceStyleLight,
        UIUserInterfaceStyleDark,
    } API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);
    
    + (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.2 通过子类重写traitCollectionDidChange这个方法来监听系统设置的一些属性变化

    // 并不是每次系统调用traitCollectionDidChange:方法时,模式都有变化,也有可能是设备进行了旋转也会调用traitCollectionDidChange:方法,所以此时需要判断系统主题模式是否发生了改变,只要颜色发生改变后我们才对主题颜色进行修改。
    - (void) traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
    {
        [super traitCollectionDidChange:previousTraitCollection];
        
        UITraitCollection *traitCollection = [UITraitCollection currentTraitCollection];// 获取当前的TraitCollection
        BOOL hasUserInterfaceStyleChanged = [previousTraitCollection hasDifferentColorAppearanceComparedToTraitCollection:traitCollection];
        // 根据当前模式更新视图
    }
    

    补充功能:
    1.如何全局关闭DarkMode?

    1.在Info.plist 文件中,添加 key 为 User Interface Style 类型String。
    2.将UIUserInterfaceStyle key 的值设置为 Light
    

    2.如何只是单独几个页面关闭DarkMode?

    // 在ios13系统下UIViewcontroller与UIView有一个新的属性 overrideUserInterfaceStyle 可以强制设置关闭暗黑模式的属性
    typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
        UIUserInterfaceStyleUnspecified,
        UIUserInterfaceStyleLight,
        UIUserInterfaceStyleDark,
    }
    
    self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
    

    3.系统主题更换之后会调用哪些方法?

    在ViewController:
    - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
    - (void)updateViewConstraints
    - (void)viewWillLayoutSubviews
    - (void)viewDidLayoutSubviews
    
    在View里:
    - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
    - (void)drawRect:(CGRect)rect
    - (void)layoutSubviews
    - (void)updateConstraints
    - (void)tintColorDidChange
    
    在UIPresentationController里:
    - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
    - (void)containerViewWillLayoutSubviews
    - (void)containerViewDidLayoutSubviews
    

    4.启动图能根据不同的mode来展示不同的图片吗?
    可以,我们可以像普通的图片那样针对深色模式设置另外的一张图片

    参考文章:关于iOS13 DarkMode的适配那些事儿iOS13 (五)暗黑模式Dark Mode深色模式适配

  • 相关阅读:
    C#中List<T>用法
    windows phone中,将crash report记录下来,写入文件,方便分析
    解决问题之,wp项目中使用MatchCollection正则表达式匹配出错
    提问的智慧
    toolkit,phonetextbox中实现用户按回车键会换行
    Hibernate主键生成策略
    hibernate.cfg.xml位置及JDBC配置
    Java与数字签名
    MyEclipse不能编译的一种解决方法
    java读文件和写文件编码方式的控制
  • 原文地址:https://www.cnblogs.com/weicyNo-1/p/14486624.html
Copyright © 2020-2023  润新知