SwiftUI Color(一)

颜色作为一个App重要的组成,需要被认真地对待。在App开发中,通常情况下,我们需要用到颜色的地方,比如背景色,比如字体颜色。

在SwiftUI中,颜色是Color。它既可以很简单,也可以很复杂。比如给一个视觉元素设置背景色为白色,可以:

swift 复制代码
VStack {
	Text("Hello World")
}
.background(.white)

看似很简单,然而需要考虑的东西还不少。比如Dark Mode下,这个页面看起来应该是如何的。 因为Text没有设置字体颜色,所以使用的是系统默认的颜色。这颜色在Light Mode下是黑色,而在Dark Mode下则是白色。 因此,上面的页面,在Dark Mode下就看不到文字了。(我就吃过这个亏,上架审核的时候,说我的App在Dark Mode下不能正常使用。) 那要如何改呢? 这里要用到colorScheme。这个是一个环境变量,表示当前页面是Light Mode还是Dark Mode。 比如上面的代码就可以改成:

swift 复制代码
VStack {
	Text("Hello World")
}
.background(colorScheme == .light ? .white : .black)

这样的做法固然没错,也很直接。但试想一下,如果一个App里每个涉及到Color的地方,都要进行这样的判断,那代码简直不忍直视。而且如果有地方忽略了,那就会给用户造成不好的体验。 UIColor可以使用public init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)根据Light或者Dark创建实例,达到自动适应Dark Mode的问题。 SwiftUI中是否有这样的方法呢?其实是有的。比如Color.primary,就会根据colorScheme改变颜色。当Light Mode的时候,primary是黑色,而Dark Mode下,primary就是白色。 我们自己怎么实现这样的功能? 这需要分情况考虑。 在低于iOS 17的系统,没法直接用代码实现,需要在Assets.xcassets文件中创建color set来实现。 !\[Pasted image 20250423100215.png] 使用的时候用名称就可以取得。let background = Color("background") 这里简单提一下,重点还是放在iOS 17之后的代码实现上。 iOS 17新增了ColorResource,上面的代码可以写成let background = Color(.background),编译器会帮忙检测background是否存在。 不过iOS 17可以用纯代码实现相应的功能,纯代码的爱好者应该会更喜欢。

swift 复制代码
public struct SchemeColor: Hashable, ShapeStyle {
    public let any: Color.Resolved?
    public let light: Color.Resolved
    public let dark: Color.Resolved

    public init(
        any: Color.Resolved,
        light: Color.Resolved,
        dark: Color.Resolved
    ) {
        self.any = any
        self.light = light
        self.dark = dark
    }

    public init(
        light: Color.Resolved,
        dark: Color.Resolved
    ) {
        any = nil
        self.light = light
        self.dark = dark
    }

    public func resolve(in environment: EnvironmentValues) -> Color.Resolved {
        switch environment.colorScheme {
        case .light:
            light
        case .dark:
            dark
        @unknown default:
            any ?? light
        }
    }
}

我们引入一个SchemeColor类型,实现HashableShapeStyle类型,resolve函数返回Color.Resolved,这样,就可以用SchemeColor创建Color了。 用到的是Color

swift 复制代码
@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)

    public init<T>(_ color: T) where T : Hashable, T : ShapeStyle, T.Resolved == Color.Resolved

初始化方法。 这样上面的实现就可以变成下面这样:

swift 复制代码
let background = Color(
	SchemeColor(
		light: .init(red: 1, green: 1, blue: 1),
		dark: .init(red: 0, green: 0, blue: 0)
	)
)
swift 复制代码
VStack {
	Text("Hello World")
}
.background(Color.background)

这样代码看起来就简洁多了,不用到处都是colorScheme == .light ? .white : .black的判断。

Color包含的内容还有许多,这一篇没法完全容纳,如果想要了解更多,可以关注我下一篇文章。

相关推荐
MDM.Plus17 小时前
苹果MDM技术演进:从远程控制到设备信任体系的构建
运维·服务器·安全·ios·mdm·手机店
韩曙亮18 小时前
【Flutter】Flutter 进程保活 ③ ( 屏幕常亮设置 | Flutter 禁止息屏、关闭自动锁屏、屏蔽系统屏保 )
android·flutter·ios·屏幕常亮·禁止息屏
2501_9159090621 小时前
IPA 深度混淆是什么意思?从混淆强度到实际效果的解读
android·ios·小程序·https·uni-app·iphone·webview
apihz1 天前
经纬度制作高清卫星图片免费 API 接口详解
开发语言·ios·swift
黄林晴1 天前
KMP 正式支持 SwiftPM:CocoaPods 迁移配置指南
android·ios·kotlin
Tisfy2 天前
iOS:压缩和解压live图(.livp)——百度一刻相册+百度网盘识别支持
ios·百度网盘·livp·live图·一刻相册
唐诺2 天前
Objective-C 之 KVC 详解
ios·objective-c·kvc
00后程序员张2 天前
iOS 打包方式汇总 从 Xcode Archive 到轻量级工具链的 IPA 构建
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
CHB3 天前
uni-app x 蒸汽模式 iOS版 性能测试基准报告 Benchmark
ios·uni-app·swiftui
大熊猫侯佩3 天前
SwiftUI 侦探笔记:iPhone 14 失踪的“刘海”与侯佩的像素诡计
swiftui·swift·apple