在 SwiftUI 中,Color(hue:saturation:brightness:) 是一个构造函数,用于生成特定的颜色。它使用 HSV 颜色模型 来表示颜色,允许你通过色相(Hue)、饱和度(Saturation)、亮度(Brightness)三个参数来定义颜色。
参数说明
1、hue: 色相,取值范围是 0.0 到 1.0。
表示颜色的种类。它通过一个圆形颜色空间定义:
0.0 是红色。
0.33 是绿色。
0.66 是蓝色。
它会在 0 和 1 之间形成一个完整的颜色环。
2、saturation: 饱和度,取值范围是 0.0 到 1.0。
表示颜色的纯度。
0.0 是灰色。
1.0 是最纯的颜色。
3、brightness: 亮度,取值范围是 0.0 到 1.0。
表示颜色的明暗。
0.0 是完全黑色。
1.0 是最亮的颜色。
使用示例
创建一组颜色
以下代码会创建红色、绿色和蓝色的颜色块:
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Text("Hue: 0.0 (Red)")
.frame(width: 200, height: 100)
.background(Color(hue: 0.0, saturation: 1.0, brightness: 1.0))
.cornerRadius(10)
Text("Hue: 0.33 (Green)")
.frame(width: 200, height: 100)
.background(Color(hue: 0.33, saturation: 1.0, brightness: 1.0))
.cornerRadius(10)
Text("Hue: 0.66 (Blue)")
.frame(width: 200, height: 100)
.background(Color(hue: 0.66, saturation: 1.0, brightness: 1.0))
.cornerRadius(10)
}
}
}
动态颜色
使用滚动位置动态调整色相(Hue)的颜色:
struct ContentView: View {
var body: some View {
ScrollView {
VStack(spacing: 20) {
ForEach(0..<50) { index in
GeometryReader { proxy in
let hue = Double(proxy.frame(in: .global).minY / UIScreen.main.bounds.height)
Text("Item \(index)")
.frame(width: 200, height: 100)
.background(Color(hue: hue.truncatingRemainder(dividingBy: 1), saturation: 1.0, brightness: 1.0))
.cornerRadius(10)
}
.frame(height: 100)
}
}
}
}
}
注意事项
1、取值范围:
hue 应在 0.0 到 1.0 之间,否则需要用 truncatingRemainder(dividingBy:) 限制。
注:truncatingRemainder(dividingBy:)为浮点数除法的余数
let remainder = 7.5.truncatingRemainder(dividingBy: 2.0) // 输出: 1.5
saturation 和 brightness 建议保持在有效范围内。
2、颜色渐变:
如果 hue 是动态变化的,可以创造流畅的渐变效果。
3、性能优化:
当大量动态计算颜色时,注意优化 GeometryReader 和视图的布局性能。
总结
通过Color的HSV构造函数可以在实际应用中,通过控制色相的范围(0 – 1)来改变颜色,比较适合应用于GeometryReader等涉及空间位置的代码,以便调整视图的颜色。
在下面的代码中,通过GeometryReader获取Text视图最小的Y值。
hue.truncatingRemainder(dividingBy: 1)
根据truncatingRemainder方法的计算,来调整Text视图的背景颜色。
struct ContentView: View {
var body: some View {
GeometryReader { fullView in
ScrollView(.vertical) {
ForEach(0..<50) { index in
GeometryReader { proxy in
let minY = proxy.frame(in: .global).minY
let hue = minY / fullView.size.height // 根据滚动位置动态调整色相
Text("Row #\(index)")
.font(.title)
.frame(maxWidth: .infinity)
.background(Color(hue: hue.truncatingRemainder(dividingBy: 1), saturation: 1, brightness: 1))
.scaleEffect(minY > 200 ? (minY < 600 ? 1 : 1.5) : 0.5)
.rotation3DEffect(.degrees(minY - fullView.size.height / 2) / 5, axis: (x: 0, y: 1, z: 0))
.opacity(minY > 200 ? 1 : minY / 200)
}
.frame(height: 40)
}
}
}
}
}
最终的实现效果为:
相关文章
1、SwiftUI数值计算的方法:https://fangjunyu.com/2024/12/15/swiftui%e6%95%b0%e5%80%bc%e8%ae%a1%e7%ae%97%e7%9a%84%e6%96%b9%e6%b3%95/
2、Layout and geometry: Wrap up:https://www.hackingwithswift.com/books/ios-swiftui/layout-and-geometry-wrap-up