Using buttonRepeatBehavior for repetitive interactions
Sometimes, we need to offer users the ability to interact with buttons in very specific ways. Until now, SwiftUI did not provide a way to perform repetitive actions when a user holds down a button. However, with iOS 17, we can now offer this functionality using buttonRepeatBehavior(_:)
.
struct Sample: View {
@State private var counter = 0
var body: some View {
VStack {
Text("\(counter)")
Button {
counter += 1
} label: {
Label("Increment", systemImage: "plus.circle.fill")
}
.buttonRepeatBehavior(.enabled)
}
.font(.largeTitle)
}
}
In this view, we have a Text
that displays the value of the private variable counter
. We also have a button that increments counter
when pressed. This button has the particularity of having the modifier .buttonRepeatBehavior(.enabled)
.
When we press the button once, we see how counter
increases by one. However, if we hold down the button for an extended period, we see how it continues to increase.
This modifier can be used in macOS applications, so interactions like holding down the spacebar will have the same effect as holding down the button directly.
Types of Behavior
The buttonRepeatBehavior(_:)
modifier accepts one of the following values:
enabled
: the one we used in the example, which activates the repeat behavior.automatic
: this is the default value; the behavior will be chosen based on the context.disabled
: disables the behavior.
Environment Variable
SwiftUI provides us with an environment variable so that we can check the value of buttonRepeatBehavior
globally. To do this, we declare the variable in our view like this:
@Environment(\.buttonRepeatBehavior) private var behavior
This way, we can access the default value and take actions based on it. At the moment, it is not allowed to change these values directly. If we try to do the following:
struct AsyncLearnApp: App {
var body: some Scene {
WindowGroup {
Sample()
.environment(\.buttonRepeatBehavior, .enabled)
}
}
}
We will receive the error:
Key path value type 'WritableKeyPath<EnvironmentValues, ButtonRepeatBehavior>' cannot be converted to contextual type 'KeyPath<EnvironmentValues, ButtonRepeatBehavior>'
This means that we cannot change this value globally. However, this could change once we have the official release of iOS 17 and Xcode 15.
If you want to read the Spanish version of this article, you can find it here: https://asynclearn.com/blog/usando-button-repeat-behavior-para-interacciones-repetitivas/