SwiftUI ButtonStyle - how to check if button is disabled or enabled?

You can access the enabled value through environment directly in the ButtonStyle, eg:

struct MyButtonStyle: ButtonStyle {
    @Environment(\.isEnabled) var isEnabled
    
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .background(!isEnabled ? Color.black : (configuration.isPressed ? Color.red : Color.blue))
            
    }
    
}

Tweaked up a bit on @hasen answer so as to make things more configurable

struct MyButtonStyle: ButtonStyle {
    var foreground = Color.white
    var background = Color.blue
    
    func makeBody(configuration: ButtonStyle.Configuration) -> some View {
        MyButton(foreground: foreground, background: background, configuration: configuration)
    }

    struct MyButton: View {
        var foreground:Color
        var background:Color
        let configuration: ButtonStyle.Configuration
        @Environment(\.isEnabled) private var isEnabled: Bool
        var body: some View {
            configuration.label
                .padding(EdgeInsets(top: 7.0, leading: 7.0, bottom: 7.0, trailing: 7.0))
                .frame(maxWidth: .infinity)
                .foregroundColor(isEnabled ? foreground : foreground.opacity(0.5))
                .background(isEnabled ? background : background.opacity(0.5))
                .opacity(configuration.isPressed ? 0.8 : 1.0)
        }
    }
}

Usage

       Button(action: {}) {
            Text("Hello")
        }.buttonStyle(MyButtonStyle(foreground: .white, background: .green))

I found the answer thanks to this blog: https://swiftui-lab.com/custom-styling/

You can get the enabled state from the environment by creating a wrapper view and using it inside the style struct:

struct MyButtonStyle: ButtonStyle {
    func makeBody(configuration: ButtonStyle.Configuration) -> some View {
        MyButton(configuration: configuration)
    }

    struct MyButton: View {
        let configuration: ButtonStyle.Configuration
        @Environment(\.isEnabled) private var isEnabled: Bool
        var body: some View {
            configuration.label.foregroundColor(isEnabled ? Color.green : Color.red)
        }
    }
}

This example demonstrates how to get the state and use it to change the appearance of the button. It changes the button text color to red if the button is disabled or green if it's enabled.


Another option would be to pass a disabled Boolean value to your ButtonStyle, and then use the allowsHitTesting modifier on the label to effectively disable the button:

struct MyButtonStyle: ButtonStyle {
    let disabled: Bool

    func makeBody(configuration: Self.Configuration) -> some View {
        configuration
            .label
            .allowsHitTesting(!disabled)
    }
}

Tags:

Ios

Swift

Swiftui