【问题标题】:macOS SwiftUI button foreground color changes after dark/light appearance changemacOS SwiftUI 按钮前景色在深色/浅色外观更改后更改
【发布时间】:2022-01-01 11:25:00
【问题描述】:

所以我在操场上运行下面的代码,我看到 2 个浅色按钮,然后我切换到深色模式。作为 SwiftUI 框架的一部分,这两个按钮都将前景色更新为灰白色。然后我点击一个按钮,其他按钮上的前景色变为灰色。请参阅下面的视频。 使用 Xcode 13.1


import SwiftUI
import PlaygroundSupport

struct ContentView: View {
    var body: some View {
        VStack {
            HStack {
                Text("Current")
                    .font(.subheadline)
                    .fontWeight(.semibold)
                    .foregroundColor(.gray)
                    .frame(maxWidth: .infinity, alignment: .leading)
                Label("43.672490, -79.388932", systemImage: "location")
                    .frame(width: 175, alignment: .trailing)
            }
            HStack {
                Button {} label: {
                    Text("???? Set Location")
                        .frame(width: 95)
                }
                Spacer()
                Button {} label: {
                    Text("???? Set Travel")
                        .frame(width: 95)
                }
            }
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

Appearance change button issue video

任何人都遇到过这个错误并有解决方案,还是我必须创建一个自定义按钮并手动修改前景色?

【问题讨论】:

    标签: button swiftui


    【解决方案1】:

    前景色确实似乎无法在明暗模式之间正确调整。但是,我可以通过将其添加为按钮上的.foregroundColor() 来使用考虑不同外观的颜色来修复它:

    struct ContentView: View {
        let buttonTextColor = Color(.secondaryLabelColor)
        var body: some View {
            VStack {
                HStack {
                    Text("Current")
                        .font(.subheadline)
                        .fontWeight(.semibold)
                        .foregroundColor(.gray)
                        .frame(maxWidth: .infinity, alignment: .leading)
                    Label("43.672490, -79.388932", systemImage: "location")
                        .frame(width: 175, alignment: .trailing)
                }
                HStack {
                    Button {} label: {
                        Text("? Set Location")
                            .frame(width: 95)
                    }
                    .foregroundColor(buttonTextColor)
                    Spacer()
                    Button {} label: {
                        Text("? Set Travel")
                            .frame(width: 95)
                    }
                    .foregroundColor(buttonTextColor)
                }
            }
        }
    }
    

    这是值得向 Apple 报告错误的,恕我直言。

    编辑:

    要完全模仿按钮,您需要使用自定义ButtonStyle。我没有完全匹配颜色,你可以自己做,但这里是它的工作原理:

    struct ContentView: View {
        @Environment(\.colorScheme) var colorScheme
        var buttonTextColor = Color(.labelColor)
        
        var body: some View {
            VStack {
                HStack {
                    Text("Current")
                        .font(.subheadline)
                        .fontWeight(.semibold)
                        .foregroundColor(.gray)
                        .frame(maxWidth: .infinity, alignment: .leading)
                    Label("43.672490, -79.388932", systemImage: "location")
                        .frame(width: 175, alignment: .trailing)
                }
                HStack {
                    Button {} label: {
                        Text("? Set Location")
                            .frame(width: 95)
                    }
                    .buttonStyle(CustomButtonStyle())
                    
                    Spacer()
                    Button {} label: {
                        Text("? Set Travel")
                            .frame(width: 95)
                    }
                }
            }
        }
    }
    
    struct CustomButtonStyle : ButtonStyle {
        @Environment(\.colorScheme) var colorScheme
        
        func makeBody(configuration: Configuration) -> some View {
            if colorScheme == .light {
            configuration.label
                        .foregroundColor(configuration.isPressed ? Color.white : Color.black)
                        .padding(3)
                        .background(RoundedRectangle(cornerRadius: 5)
                                        .fill(configuration.isPressed ? Color.blue : Color.white)
                                        .shadow(color: .gray, radius: 2, x: 0, y: 2)
                        )
            } else {
                configuration.label
                            .foregroundColor(Color.white)
                            .padding(3)
                            .background(RoundedRectangle(cornerRadius: 5)
                                            .fill(configuration.isPressed ? Color.blue : Color.gray)
                                            .shadow(color: .gray, radius: 2, x: 0, y: 2)
                            )
            }
        }
    }
    

    【讨论】:

    • 这可能是我试图重现它的方式,但我在 macOS Monterey 12.0.1 上看不到这种行为的价值。
    • 但它会更新 onTap。因此,在浅色模式下,前景标签颜色为黑色,onTap 变为白色,而在深色模式下,前景标签颜色为灰白色,而 onTap 则保持灰白色。上面的 .forgroundColor 解决方案没有考虑 onTap 的变化。要尝试不同之处,请打开 System Pref > Security and Privacy 并点击锁定图标(左下角)并观察 Cancel 按钮的行为。谢谢!
    • 答案已更新。
    猜你喜欢
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 2018-12-03
    • 2021-04-28
    相关资源
    最近更新 更多