ROMA-iOS适配深色模式总结

京东云开发者
• 阅读 3

一、背景

深色模式在低光环境下(如夜间使用)可以显著减少屏幕发出的蓝光,降低眼睛疲劳,减轻视觉压力。深色背景配合浅色文字能提供更好的对比度和可读性,减少眩光,让内容更易于阅读。深色模式还可以显著节省电量,延长设备的电池续航时间。随着深色模式的普及,越来越多的用户习惯并偏好深色界面。

京东金融App自8.0.20版本支持深色模式,可在设置->通用->深色模式中打开深色模式的设置页面,选择是否启用深色模式。ROMA框架也在此版本全面支持深色模式的设置,本文详细介绍跨端框架ROMA适配深色模式的过程。

二、ROMA配置和使用

APP深色模式的设置,提供如下选择,可以强制设置普通模式(浅色模式)、深色模式和跟随系统。可以看到在将App切换为深色模式时,页面视图由普通模式切换深色模式时原有视图并未重建,视图模式的转换也非常顺畅,体验很好。

ROMA-iOS适配深色模式总结



1.视图的显示模式设置

ROMA针对所有标签(包括页面)提供 theme-mode 属性,表示当前视图在什么模式下显示。提供以下三种模式可选:

1:表示强制浅色模式 2:表示强制深色模式 3:表示跟随模式(节点设置跟随,表示跟随父节点。页面设置跟随,表示跟随系统。若未设置:页面为1,标签3)

如下示例代码,设置当前页面 theme-mode=3 表示跟随window(window设置跟随系统),div标签设置 theme-mode="1" 表示强制浅色,text标签未设置,则默认为 theme-mode="3",跟随父节点div,因次text标签也是浅色。

<template theme-mode=3>
    <div style="align-self: stretch; height: 100px; margin: 10px;" theme-mode="1">
          <text style="color:#000000; font-size: 12px;"> 文本测试 </text>
    </div>
</template> 

通过设置 theme-mode 属性,业务可以灵活的定制页面和视图的显示模式。既可实现整体视图跟随父节点的模式,也可针对特殊节点强制深色或者浅色显示,更大程度的满足业务在不同场景下的需求,具体效果可参考下图,其中数字表示当前节点对应的 theme-mode 的值。

ROMA-iOS适配深色模式总结

2.视图的颜色设置

理想情况下业务可以做到零修改就能完成深色模式的适配,前提是App需要高度依赖一套完整的、规范的颜色映射表(普通模式下的颜色color要有对应的深色模式下的颜色值color-dark,没有则不映射),且设计师要按照映射表上的颜色来设计UI设计稿。这样在模式切换时就可以自动调整视图的颜色。

配置表的颜色映射流程可参考下图:

ROMA-iOS适配深色模式总结

但业务场景复杂多样,为了兼容更多的业务场景,ROMA也向所有视图提供了针对深色模式的特定样式配置 xxx-dark ,来定制深色模式下的UI样式。如下示例代码,提供了 background-color-dark 字段可以配置深色模式下视图的背景色,color-dark 字段设置深色模式下文本的颜色, src-dark 字段设置深色模式下图片的资源。

 <div style="background-color: white; background-color-dark: '#EF4034';">
      <text style="color: '#666666'; color-dark:'#F9F9F9';"> 文本测试 </text>
      <img src="https://img0.baidu.com/it/u=3838093562,4126749835&fm=253&fmt=auto&app=138&f=JPEG?w=1144&h=500" 
           src-dark="https://imgs.699pic.com/images/500/465/562.jpg!list1x.v2">
</div>

三、视图模式切换原理分析

ROMA 只提供了简单配置就可以让业务适配视图在深色模式的显示,极大简化了业务的适配工作,其实App切换深色模式的处理流程涉及视图层级的方方面面,下面以iOS端为例,着重从视图层级的变化上介绍模式切换所触发的整个流程。

1.UITraitEnvironment 协议详解

UITraitEnvironment 是 iOS 中一个基础协议,各类视图和控制器都已实现了这个协议,用于监听和处理界面环境特征的变化。它是 iOS 自适应布局和外观系统的核心组成部分,使应用能够响应各种环境变化,如深浅模式切换、设备旋转或者尺寸类别变化。

@protocol UITraitEnvironment <NSObject>
@property (nonatomic, readonly) UITraitCollection *traitCollection API_AVAILABLE(ios(8.0));
/*! To be overridden as needed to provide custom behavior when the environment's traits change. */
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection API_DEPRECATED("Use the trait change registration APIs declared in the UITraitChangeObservable protocol", ios(8.0, 17.0), visionos(1.0, 1.0)) API_UNAVAILABLE(watchos);
@end

在iOS17之后推荐使用 UITraitChangeObservable 协议,可更精细定制要监控的特征值,并将新旧特征值都封装到hander中处理,使用起来更方便。

API_AVAILABLE(ios(17.0), tvos(17.0)) API_UNAVAILABLE(watchos) NS_SWIFT_UI_ACTOR
@protocol UITraitChangeObservable
- (id<UITraitChangeRegistration>)registerForTraitChanges:(NSArray<UITrait> *)traits withHandler:(UITraitChangeHandler)handler;
- (id<UITraitChangeRegistration>)registerForTraitChanges:(NSArray<UITrait> *)traits withTarget:(id)target action:(SEL)action;
- (id<UITraitChangeRegistration>)registerForTraitChanges:(NSArray<UITrait> *)traits withAction:(SEL)action;
- (void)unregisterForTraitChanges:(id<UITraitChangeRegistration>)registration;
@end

2.系统特征值改变对各层级视图的影响

iOS的核心类 UIScreen、UIWindow、UIViewController、UIView 等都实现了 UITraitEnvironment 协议,特征集合通过视图层次结构自上而下传递:

1.系统级特征由 UIScreen 提供

2.UIWindow 从 UIScreen 继承特征

3.根视图控制器从 UIWindow 继承特征

4.子视图控制器从父视图控制器继承特征

5.视图从其视图控制器继承特征

6.子视图从父视图继承特征

7.layer层监听对应视图层的特征来调整自身的特征

以下展示系统显示模式由浅色切换为深色时各层级视图特征值的变化过程。

ROMA-iOS适配深色模式总结

3.视图的颜色设置

如果是视图的直接颜色属性,比如文本颜色textColor,视图的背景色backgroundColor等,可以通过DynamicColors 直接设置,这样在视图模式发生变化的时候,会自动获取对应模式的颜色值。

UIColor* dycolor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
       if ([traitCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
           return  lightResoledColor;
       } else {
           return darkResoledColor ? darkResoledColor : (lightResoledColor ? lightResoledColor : [UIColor clearColor]);
       }
}];
view.backgroundColor = dycolor;

4.视图的其他设置

对于layer层颜色、图片资源变化、lottie的资源切换等,可以向view层注册状态变更的事件回调,在视图的显示特征的发生变化时,调整视图的显示。如下示例在监测到view的模式发生变化时,调整图层的边框颜色。

UIColor* borderColor = jr_themeColorForTrans(_bordercolor_light, _bordercolor_dark); 
CAShapeLayer* borderLayer = [[CAShapeLayer alloc]init];
__weak CAShapeLayer* __weakBorderLayer = borderLayer;
[self.view jr_registerForJRThemeChangesWithHandler:^(JRThemeModeStyle style) {
       [CATransaction begin];
       [CATransaction setDisableActions:YES];
       __weakBorderLayer.strokeColor = borderColor.CGColor;
       [CATransaction commit];
 } key:@"jr_trans_layer_border_color_key"];

四、总结

ROMA作为一个现代化的跨端框架,深色模式的适配不仅是一项功能,更是我们对用户体验、设备兼容性和技术趋势的全面考量。我们相信,这一更新将为开发者提供更大的灵活性,并最终为用户带来更加优质的产品体验。同时,在深色模式开发的过程中,我们也梳理出多主题切换的实现方案,如有需要,可快速完成多主题的适配。

点赞
收藏
评论区
推荐文章
想天浏览器 想天浏览器
3年前
想天浏览器3.2正式版推送更新
快来看更新!经过我们一个多月的努力开发,想天浏览器3.2正式版推送更新啦。    图片下方是本次更新的主要内容↓↓浅色模式3.2改进的深色模式新增内容1.兼容插件机制插件的crx形式安装插件的解压包形式安装插件的工具栏展示与否设置插件的启用禁用chrome商店安装到想天浏览器,同时支持下载
小尉迟 小尉迟
2年前
苹果软件Noir:为所有网站应用深色模式
在夜晚使用Mac的时候,我们已经习惯打开深色模式,享受发着微光的屏幕带来的平静与沉浸感.直到打开一个不支持深色模式的网站。再也没有什么比突然出现的刺眼亮光更让人难受了!如何将网页更改为深色模式?Safari浏览器扩展《Noir》能为你通过《Safari浏览
布袋罗汉 布袋罗汉
2年前
快速切换One Switch 1.29
OneSwitch是一款Mac应用程序,它可以帮助用户快速切换Mac的不同设置和模式。它提供了一个简单的界面,让用户可以轻松地切换夜间模式、显示器分辨率、音频输入和输出设备、WiFi网络以及其他常用功能,例如剪贴板历史记录、屏幕截图、屏幕录制等。用户可以将
Stella981 Stella981
3年前
Android状态栏黑色字体
前言由于公司项目的欢迎页是白色的,,修改状态栏颜色后,导致状态栏的白色字体完全被覆盖了,联想到之前在QQ、UC等一些app上都见到过状态栏的字体是深色的,想着,,必定有解决的方案。于是,有了本篇blog。参考下面是我在网上找到的两篇文章1.白底黑字!Android浅色状态栏黑色字体模式(https://www.os
Wesley13 Wesley13
3年前
00_设计模式之语言选择
设计模式之语言选择设计模式简介背景设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式(Designpattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的
Wesley13 Wesley13
3年前
Java适配器设计模式 的优缺点
1\.定义:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。2\.适配器模式的本质转换匹配,复用功能。3\.优点:更好的复用如果功能是已经有了的,只是接口不兼容,那么通过适配器模式就可以让这些功能得到更好的复用。更好的可扩展在实现适配器功能的时候,可以调用自己
公孙晃 公孙晃
2年前
AlDente Pro for Mac v1.22 最新中文版
是一款适用于Mac操作系统的小工具,可以帮助您限制电池充电量以延长电池寿命。通常情况下,电池在充满的状态下会继续接受电源充电,这可能会导致电池寿命缩短。使用AlDentePro,您可以设置电池只充到特定的充电水平,例如80%或90%,从而减少对电池的压力,
子桓 子桓
1年前
mac电池最大充电限制 AlDente Pro for Mac最新
AlDentePro是一款适用于Mac操作系统的小工具,可以帮助用户限制电池充电量以延长电池寿命。具体来说,使用AlDentePro,用户可以:设置电池只充到特定的充电水平,例如80%或90%,从而减少对电池的压力,延长其使用寿命。在菜单栏中显示当前电池状
子桓 子桓
1年前
mac电池最大充电限制推荐: AlDente Pro激活中文最新版
AlDentePro是一款适用于Mac操作系统的电池管理工具,旨在延长电池寿命和提高电池性能。通过限制电池充电的最大百分比,避免电池过度充电,从而减少电池损耗和延长使用寿命。该软件主要的功能包括:限制电池充电量:AlDentePro可以帮助用户限制电池充电
还在自己实现责任链?我建议你造轮子之前先看看这个开源项目
1.前言设计模式在软件开发中被广泛使用。通过使用设计模式,开发人员可以更加高效地开发出高质量的软件系统,提高代码的可读性、可维护性和可扩展性。责任链模式是一种常用的行为型设计模式,它将请求沿着处理链进行发送,直到其中一个处理者对请求进行处理为止。在责任链模