当我以编程方式检索
accent
颜色时,它会返回灯光模式下的强调色。但是,当我单独检索颜色时,它会返回正确的颜色。我该如何解决这个问题?
import SwiftUI
extension Color {
// Function to get RGB components from Color
private func getRGBA() -> (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
let uiColor = UIColor(self)
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return (red, green, blue, alpha)
}
// Generate array of colors between two colors
static func colorRange(from startColor: Color, to endColor: Color, count: Int) -> [Color] {
guard count > 1 else { return [startColor] }
let start = startColor.getRGBA()
let end = endColor.getRGBA()
let redDelta = end.red - start.red
let greenDelta = end.green - start.green
let blueDelta = end.blue - start.blue
let alphaDelta = end.alpha - start.alpha
return (0 ..< count).map { step in
let progress = CGFloat(step) / CGFloat(count - 1)
let red = start.red + redDelta * progress
let green = start.green + greenDelta * progress
let blue = start.blue + blueDelta * progress
let alpha = start.alpha + alphaDelta * progress
return Color(UIColor(red: red, green: green, blue: blue, alpha: alpha))
}
}
}
struct ColorRangeExamples: View {
var body: some View {
VStack(spacing: 30) {
Color.accent.frame(height: 100).cornerRadius(10)
// Example 1: 5 colors between accent and secondary
let example1 = Color.colorRange(from: .accent, to: .secondary, count: 5)
HStack(spacing: 0) {
ForEach(0 ..< example1.count, id: \.self) { index in
example1[index]
}
}
.frame(height: 50)
.cornerRadius(10)
}
.padding()
}
}
#Preview {
ColorRangeExamples()
}
UIColor.getRGBA
不尊重当前的配色方案。
resolve(in:)
来获取 RGBA 值。此方法采用包含配色方案信息的 EnvironmentValues
。它给你一个Color.Resolved
,从中你可以直接获取RGBA值。
extension Color {
func getRGBA(env: EnvironmentValues) -> (red: Float, green: Float, blue: Float, alpha: Float) {
let resolved = resolve(in: env)
return (resolved.red, resolved.green, resolved.blue, resolved.opacity)
}
}
同样,
colorRange
也需要采用这样的EnvironmentValues
参数。
static func colorRange(from startColor: Color, to endColor: Color, count: Int, env: EnvironmentValues) -> [Color.Resolved] {
guard count > 1 else { return [startColor.resolve(in: env)] }
let start = startColor.getRGBA(env: env)
let end = endColor.getRGBA(env: env)
let redDelta = end.red - start.red
let greenDelta = end.green - start.green
let blueDelta = end.blue - start.blue
let alphaDelta = end.alpha - start.alpha
return (0 ..< count).map { step in
let progress = Float(step) / Float(count - 1)
let red = start.red + redDelta * progress
let green = start.green + greenDelta * progress
let blue = start.blue + blueDelta * progress
let alpha = start.alpha + alphaDelta * progress
return Color.Resolved(red: red, green: green, blue: blue, opacity: alpha)
}
}
在您看来,使用
@Environment(\.self)
即可获得 EnvironmentValues
。
struct ColorRangeExamples: View {
@Environment(\.self) var env
var body: some View {
VStack(spacing: 30) {
Color.accent.frame(height: 100).cornerRadius(10)
// Example 1: 5 colors between accent and secondary
let example1 = Color.colorRange(from: .accent, to: .secondary, count: 5, env: env)
HStack(spacing: 0) {
ForEach(0 ..< example1.count, id: \.self) { index in
Color(example1[index])
}
}
.frame(height: 50)
.cornerRadius(10)
}
.padding()
}
}