如果在 swiftUI 中禁用按钮,如何更改按钮背景颜色

P5y*_*cH0 4 swiftui

我正在尝试创建一个按钮样式,如果按钮被禁用,该按钮样式具有不同的背景颜色。

我怎么做?我创建了下面的代码来对我自己引入的变量做出反应,但是是否可以让它对按钮 .disabled() 状态做出反应?

我的代码:

struct MyButtonStyle: ButtonStyle {
    var enabledState = false

    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .foregroundColor(Color.white)
            .padding(10)
            .padding(.horizontal, 20)
            .background(self.enabledState ? Color(UIColor.orange) : Color(UIColor.lightGray))
            .cornerRadius(20)
            .frame(minWidth: 112, idealWidth: 112, maxWidth: .infinity, minHeight: 40, idealHeight: 40, maxHeight: 40, alignment: .center)
            .scaleEffect(configuration.isPressed ? 0.9 : 1.0)
    }
}

struct ContentView: View {
    @State private var buttonEnabled = false

    var body: some View {
        HStack {
            Button("Button") {
                self.buttonEnabled.toggle()
                print("Button pressed")
            }
        }
        .buttonStyle(MyButtonStyle(enabledState: self.buttonEnabled))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

Asp*_*eri 5

跟踪.disabledEnvironmentValues.isEnabled显示这种状态。但环境值仅适用于视图,并且不适用于样式。

因此,解决方案是创建跟踪 isEnabled 的自定义按钮并将其传递到自己的样式中。

以下是解决方案的演示(MyButtonStyle未更改)。使用 Xcode 12b 进行测试。

struct MyButton: View {

    let title: String
    let action: () -> ()

    @Environment(\.isEnabled) var isEnabled // to handle own state !!

    init(_ title: String, action: @escaping () -> ()) {
        self.title = title
        self.action = action
    }

    var body: some View {
        Button(title, action: action)
            .buttonStyle(MyButtonStyle(enabledState: isEnabled))
    }
}

struct ContentView: View {
    @State private var buttonEnabled = true

    var body: some View {
        HStack {
            MyButton("Button") {            // << here !!
                self.buttonEnabled.toggle()
                print("Button pressed")
            }
            .disabled(!buttonEnabled)       // << here !!
        }
    }
}
Run Code Online (Sandbox Code Playgroud)