SwiftUI has the handy .accessiblityAction()
ViewModider that adds an accessibility action to a view that you are creating. Keyboard users and VO users can learn about the actions attached to the View and trigger them.
I want to be able to conditionally apply an action based on a boolean. Something like this:
Button {
print("Button tapped")
} label: {
Text("Button title")
}
if addActionToButton.wrappedValue {
.accessibilityAction(named: "Button action") {
print("Button action triggered")
}
}
You can't put a ViewModifier like accessibilityAction
inside an if
statement however.
.accessibilityLabel
has a variant that takes an isEnabled
parameter. When the isEnabled condition is false, it does not apply the accessibility label:
@State addA11Label: Bool
Button {
print("Button tapped")
} label: {
Text("Button title")
}
.accessibilityLabel("Button foo. Double-tap to do stuff.", isEnabled: addA11Label.wrappedValue)
I want a accessibilityAction
isEnabled
parameter, but no such luck.
How could I conditionally add an accessibilityAction
to my Button
(or other view)?
You could create a custom view extension that uses @ViewBuilder
to add the action only when a specified Boolean is true.
Example:
import SwiftUI
extension View {
@ViewBuilder
func conditionalAccessibilityAction(
_ condition: Bool,
name: String,
perform action: @escaping () -> Void
) -> some View {
if condition {
self.accessibilityAction(named: name, perform: action)
} else {
self
}
}
}
struct ContentView: View {
@State private var addActionToButton: Bool = true
var body: some View {
VStack {
Button {
print("Button tapped")
} label: {
Text("Button Title")
}
.conditionalAccessibilityAction(
addActionToButton,
name: "Button action"
) {
print("Button action triggered")
}
Toggle("Add Accessibility Action", isOn: $addActionToButton)
.padding()
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The extension would check the boolean and apply .accessibilityAction(named:perform:)
if the condition is met, otherwise it leaves the view unchanged.