I created a UISlider via SwiftUI, but there are just too many "step marks" along the track, which doesn't have the "look and feel" I wish to achieve. Anyone knows the trick to remove them other than turning the tint color to black?
It seems that the step/tick marks are always there as long as I pass any step values during UISlider initialization.
struct setLoggingView: View {
@State var suitability: Int
@State var elapsedRestTime: Double
var totalRestTime: Double
var stepValue: Int
var body: some View {
GeometryReader { geometry in
ScrollView {
VStack {
Text("Rested \(Int(elapsedRestTime)) seconds")
Slider(value: $elapsedRestTime,
in: 0...totalRestTime,
step: Double.Stride(stepValue),
label: {
Text("Slider")
}, minimumValueLabel: {
Text("-\(stepValue)")
}, maximumValueLabel: {
Text("+\(stepValue)")
})
.tint(Color.white)
.padding(.bottom)
Divider()
Spacer()
Text("Restfullness")
.frame(minWidth: 0, maxWidth: .infinity)
suitabilityStepper(suitability: restfullness)
Button(action: {
print("Update Button Pressed")
}) {
HStack {
Text("Update")
.fontWeight(.medium)
}
}
.cornerRadius(40)
}
.border(Color.yellow)
}
}
}
}
Until Apple improves SwiftUI, the way to do this is by providing a custom binding INSTEAD OF using the step
parameter:
Slider(value: Binding(get: { dailyGoalMinutes },
set: { newValue in
let base: Int = Int(newValue.rounded())
let modulo: Int = base % 10 // Your step amount. Here, 10.
dailyGoalMinutes = Double(base - modulo)
}),
in: 0...1440)
In this example, dailyGoalMinutes
is declared on the view like this:
@State private var dailyGoalMinutes: Double = 180.0
The slider allows the user to select between 0 and 1,440 minutes (1 day) in 10-minute increments. While the slider itself won't snap to those increments while dragging, the value of dailyGoalMinutes
will be properly constrained to multiples of 10 within the defined range.
(Note: AppKit behaves the same way; when NSSlider
does not have any tick marks visible, the slider does not snap to values.)