There is no isEnabled
property for a SwiftUI button. How can i tell if it is enabled?
In regular UIKit, i would simply do
if button.isEnabeld == true {
} else {
}
but there is no SwiftUI equivalent.
Inside a view, if you wish to react to the state set by .disabled(true)
, you can use:
@Environment(\.isEnabled) var isEnabled
Since the environment can be used from within a View or a ViewModifier, this can be used to change layout properties of a view based on the state set from outside.
Unfortunately, ButtonStyle
cannot directly use @Environment
, but you can use a ViewModifier
to inject environment values into a ButtonStyle
in order to use the value from within a ButtonStyle
:
// First create a button style that gets the isEnabled value injected
struct MyButtonStyle: ButtonStyle {
private let isEnabled: Bool
init(isEnabled: Bool = true) {
self.isEnabled = isEnabled
}
func makeBody(configuration: Configuration) -> some View {
return configuration
.label
.background(isEnabled ? .green : .gray)
.foregroundColor(isEnabled ? .black : .white)
}
}
// Then make a ViewModifier to inject the state
struct MyButtonModifier: ViewModifier {
@Environment(\.isEnabled) var isEnabled
func body(content: Content) -> some View {
return content.buttonStyle(MyButtonStyle(isEnabled: isEnabled))
}
}
// Then create a convenience function to apply the modifier
extension Button {
func styled() -> some View {
ModifiedContent(content: self, modifier: MyButtonModifier())
}
}
// Finally, try out the button and watch it respond to it's state
struct ContentView: View {
var body: some View {
Button("Test", {}).styled().disabled(true)
}
}
You can use this method to inject other things into a ButtonStyle, like size category and theme.
I use it with a custom style enum that contains all the flavours of button styles found in our design system.
From outside a view you should know if you used .disabled(true)
modifier.
From inside a view you can use @Environment(\.isEnabled)
to get that information:
struct MyButton: View {
let action: () -> Void
@Environment(\.isEnabled) private var isEnabled
var body: some View {
Button(action: action) {
Text("Click")
}
.foregroundColor(isEnabled ? .green : .gray)
}
}
struct MyButton_Previews: PreviewProvider {
static var previews: some View {
VStack {
MyButton(action: {})
MyButton(action: {}).disabled(true)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With