Apple’s built in stepper allows you to only have one step increment value, I’ve designed on that allows for two different increment values. Initial version supported 1 and 10 for the step values and is tied to an integer.
import SwiftUI
struct ContentView: View {
@State var score: Int = 0
var min: Int = 0
var max: Int = 100
var template: String = "Score: %@"
var body: some View {
Form {
Text("Expanded Stepper Example")
HStack {
Text(String(format: template, score.formatted()))
Spacer()
Button("-10") {
score = score - 10
}
.disabled(score - 10 < min)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
Button("-1") {
score = score - 1
}
.disabled(score - 1 < min)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
Button("+1") {
score = score + 1
}
.disabled(score + 1 > max)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
Button("+10") {
score = score + 10
}
.disabled(score + 10 > max)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
This of course is the first revision, and it isn’t very reusable in the current state. So the next step was to make it more reusable.
import SwiftUI
struct AdvancedStepper: View {
var value: Binding<Int>
var min: Int
var max: Int
var template: String
var body: some View {
HStack {
Text(String(format: template, value.wrappedValue.formatted()))
Spacer()
Button("-10") {
value.wrappedValue = value.wrappedValue - 10
}
.disabled(value.wrappedValue - 10 < min)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
Button("-1") {
value.wrappedValue = value.wrappedValue - 1
}
.disabled(value.wrappedValue - 1 < min)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
Button("+1") {
value.wrappedValue = value.wrappedValue + 1
}
.disabled(value.wrappedValue + 1 > max)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
Button("+10") {
value.wrappedValue = value.wrappedValue + 10
}
.disabled(value.wrappedValue + 10 > max)
.buttonStyle(BorderlessButtonStyle())
.padding(.horizontal, 4)
}
}
}
struct ContentView: View {
@State var score: Int = 0
var body: some View {
Form {
Text("Expanded Stepper Example")
AdvancedStepper(value: $score, min: 0, max: 10, template: "Score: %@")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I think I’m happy enough with this one for now. Of course I could take this further and make the step amounts customizable by the usage location.