iOS 深色模式与语义化颜色

举报
yd_217846120 发表于 2026/09/23 09:01:15 2026/09/23
【摘要】 iOS 深色模式与语义化颜色深色模式涉及的不只是背景色。文字层级、分隔线、图片、模糊材质、系统栏和第三方内容都可能在外观切换后失去对比度。若页面到处保存具体颜色,后续主题调整会非常困难。使用语义化颜色和资源变体,可以让组件描述用途,由主题决定实际表现。 一、优先使用系统语义颜色系统提供的标签、背景和分组背景颜色会随外观变化,并适配一定的可访问性设置。final class InfoCard...

iOS 深色模式与语义化颜色

深色模式涉及的不只是背景色。文字层级、分隔线、图片、模糊材质、系统栏和第三方内容都可能在外观切换后失去对比度。若页面到处保存具体颜色,后续主题调整会非常困难。使用语义化颜色和资源变体,可以让组件描述用途,由主题决定实际表现。

一、优先使用系统语义颜色

系统提供的标签、背景和分组背景颜色会随外观变化,并适配一定的可访问性设置。

final class InfoCard: UIView {
    private let titleLabel = UILabel()

    func setupAppearance() {
        backgroundColor = .secondarySystemBackground
        titleLabel.textColor = .label
        layer.borderColor = UIColor.separator.cgColor
    }
}

品牌场景需要自定义颜色时,也应使用语义名称而不是描述色值。

二、在资源中提供外观变体

颜色资源可以为浅色和深色外观提供不同值:

extension UIColor {
    static let brandPrimary = UIColor(named: "BrandPrimary")!
    static let contentBackground = UIColor(named: "ContentBackground")!
}

项目已验证为必备资源时可以按契约读取,不需要为每个颜色添加随意默认值。资源缺失应在开发测试阶段暴露。

三、CGColor 不会自动动态更新

把动态 UIColor 转为 CGColor 后,图层保存的是当前解析结果。外观变化时需要重新赋值。

override func traitCollectionDidChange(
    _ previousTraitCollection: UITraitCollection?
) {
    super.traitCollectionDidChange(previousTraitCollection)

    if traitCollection.hasDifferentColorAppearance(
        comparedTo: previousTraitCollection
    ) {
        layer.borderColor = UIColor.separator.cgColor
        chartView.updateTheme()
    }
}

相关判断能力需要符合项目最低系统版本,旧项目应使用已有兼容写法。

四、图片需要独立检查

模板图标可以通过 tint 使用动态颜色。照片通常不需要变化,但插画、阴影和带透明边缘的图片可能需要深色变体。

不要对所有图片简单反色。品牌标识、人物照片和业务图表反色后会改变含义。资源目录中的外观变体更适合设计明确的替换。

五、状态颜色仍要保持语义

成功、警告、错误和涨跌颜色需要在两种背景下都清晰。颜色不能成为唯一信息来源,还应配合文字或符号。

禁用状态不要只依赖整体透明度,因为叠加在不同背景上结果不可控。使用主题中定义的禁用前景与背景更稳定。

六、处理模糊与材质

系统材质会根据当前外观调整,但自定义半透明颜色可能与底层内容产生不可预测的对比度。弹窗、导航栏和浮层应在真实页面背景上检查,而不是只看独立色板。

复杂透明叠层还会增加渲染成本,性能敏感列表中应谨慎使用。

七、同步系统界面

状态栏图标样式、导航栏、标签栏、键盘和系统弹窗应与页面外观一致。自定义容器需要把外观选择传递给子控制器,不能只改根视图背景。

如果某个业务页面强制固定外观,应明确范围,并验证弹出的控制器不会突然切换到另一主题。

八、混合页面约定主题

原生容器与 H5 页面可以传递“浅色、深色、跟随系统”等语义状态,由页面内部设计令牌解析。不要将大量具体色值通过桥接发送,这会让两端主题体系互相耦合。

页面尚未加载完成时也需要保存最新主题,准备后立即应用,避免首次闪烁。

九、测试动态切换

外观可能在应用运行中改变,不能只在冷启动时读取一次。测试应覆盖:

  • 应用前台时切换系统外观。
  • 页面已经展示的图层颜色。
  • 弹窗和子控制器。
  • 图片与空状态插画。
  • 大字号和增强对比设置。
  • 截图、分享卡片和打印内容。

视觉截图可以帮助发现遗漏,但关键文字仍要人工检查可读性。

十、避免散落判断

业务代码不应到处判断当前是否深色并选择具体颜色。主题服务、资源变体和语义令牌负责解析,业务组件只引用用途。

只有图表算法等确实需要根据外观调整多项参数时,才接收统一主题模型。

总结

iOS 深色模式应建立在语义化颜色上。优先使用系统动态色,自定义资源提供外观变体,注意图层颜色需要重新解析,并让图片、系统容器和混合页面同步变化。集中主题规则后,业务页面无需反复判断外观,也更容易保证对比度。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。