In the watchOS Fitness app, when you change your goals using the Digital Crown, a focus ring appears around the stepper. Something I can't understand is how the green focus ring is not centered around the stepper buttons (which is the default behavior). Furthermore, I don't understand how the goal text and captions inside the stepper label are also not centered within the stepper.
A final behavior I don't understand is when the goal number transitions from 999 to 1000, the stepper changes height, but doesn't affect the height of any parent views.
import SwiftUI
struct ContentView: View {
@State private var value = 999.0
var body: some View {
VStack {
Text("MOVE GOAL")
.font(.subheadline)
.foregroundStyle(.red)
.padding(.top)
Stepper {
VStack {
Text("\(Int(value))")
.allowsTightening(true)
.minimumScaleFactor(value > 999 ? 0.70 : 1.0)
.lineLimit(1)
Text("CALORIES")
.font(.subheadline)
.foregroundStyle(.red)
}
} onIncrement: {
value += 1
} onDecrement: {
value -= 1
}
.tint(.red)
.digitalCrownRotation(
$value,
from: 1,
through: 9999,
by: 1,
sensitivity: .high,
isContinuous: false,
isHapticFeedbackEnabled: true
)
Button {
print("added")
} label: {
Text("Set")
.foregroundStyle(.black)
}
.tint(.red)
.buttonStyle(.borderedProminent)
.padding(.top)
}
}
}
This is the code I've been able to get as close as possible without delving into GeometryReader, where I've had zero luck modifying the positioning of the label within the stepper.
A final behavior I don't understand is when the goal number transitions from 999 to 1000, the stepper changes height, but doesn't affect the height of any parent views.
Did you try overlay
? The following code uses Spacer
to push the text and button to the top and bottom, and uses overlay
to show the stepper
:
VStack {
Text("MOVE GOAL") ...
Spacer()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding([.top, .bottom], 50) // Make enough space for the stepper.
.overlay {
Stepper ...
}
Button ...
}
Something I can't understand is how the green focus ring is not centered around the stepper buttons (which is the default behavior). Furthermore, I don't understand how the goal text and captions inside the stepper label are also not centered within the stepper.
Did you mean the space on the top is larger than the one on the bottom? I guess that's related to that The goal text has larger font size. You can try to adjust the space and alignment iin the following way:
Stepper {
VStack(alignment: .center) { // Center the text
Text("\(Int(value))")
.allowsTightening(true)
.minimumScaleFactor(value > 999 ? 0.70 : 1.0)
.lineLimit(1)
Text("CALORIES")
.font(.subheadline)
.foregroundStyle(.red)
.padding(.bottom) // Add more space.
}
}
Best,
——
Ziqiao Chen
Worldwide Developer Relations.