SwiftUI.cc
Snippets
ControlsValue InputBeginner

SwiftUI Slider Range, Step, and Labels

Slider binds a continuous value to a track. Set bounds and step, add min/max images, react to editing phases with onEditingChanged, and tint the filled track.

3 min readUpdated 2026-06
Brightness slider with editing feedback
import SwiftUI

struct BrightnessControl: View {
    @State private var level = 0.6
    @State private var isDragging = false

    var body: some View {
        VStack(spacing: 8) {
            Slider(value: $level, in: 0...1) {
                Text("Brightness")
            } minimumValueLabel: {
                Image(systemName: "sun.min")
            } maximumValueLabel: {
                Image(systemName: "sun.max")
            } onEditingChanged: { editing in
                isDragging = editing
            }
            .tint(.orange)

            Text(level, format: .percent.precision(.fractionLength(0)))
                .font(.caption.monospacedDigit())
                .foregroundStyle(isDragging ? .primary : .secondary)
        }
        .padding()
    }
}

Slider preview

Continuous by default, stepped on request

Slider(value: $level, in: 0...1) maps the track to your bounds. Adding step: 0.1 snaps the committed value while the thumb still drags smoothly — best of both for values like font size or playback speed.

The three-label form

The full initializer takes a hidden accessibility label plus visible minimumValueLabel/maximumValueLabel views — conventionally small/large icons of the same symbol:

Slider(value: $volume) { Text("Volume") }
    minimumValueLabel: { Image(systemName: "speaker") }
    maximumValueLabel: { Image(systemName: "speaker.wave.3") }

Editing phases

Updating a live preview every tick is fine for cheap work; for expensive consequences (re-rendering a filtered photo, hitting an API) use onEditingChanged to act once when the finger lifts. The pattern: bind the cheap preview to the value, gate the costly commit behind editing == false.

Common mistakes

  • No numeric readout for ranges where the exact value matters.
  • Steps finer than finger precision, making targets unreachable.
  • Saving to disk on every value change instead of at editing end.

Related reference