Using buttonRepeatBehavior for repetitive interactions

AsyncLearn
2 min readMar 11, 2024

--

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.

Example of how a button behaves with enabled buttonRepeatBehavior

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/

--

--

AsyncLearn

Stay up-to-date in the world of mobile applications with our specialised blog.