错误的深色模式颜色强调

问题描述 投票:0回答:1

当我以编程方式检索

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()
}

Preview in Light and Dark mode

swiftui
1个回答
0
投票

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()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.