Is there a way to define discrete steps for a Slider?

Viewed 201

Currently I'm doing this.

Slider(value: $object, in: 500...3000, step: 500)

I'd love to do something along the lines of

step: 100, 500, 600, 1000, 10000
2 Answers

Here is a possible approach - wrap system Slider into custom slider with remapping logic.

Demo (simple variant) is prepared & tested with Xcode 13 / iOS 15

demo

struct TestIrregularSliderView: View {
    @State private var current = 500
    var body: some View {
        VStack {
            IrregularSlider(value: $current, in: [100, 500, 600, 1000, 10000])
            Text("Value: \(current)")
        }
    }
}

struct IrregularSlider<T: Comparable>: View {
    @Binding var value: T
    let values: [T]
    private let upperBound: Float
    @State private var index: Int

    init(value: Binding<T>, in values: [T]) {
        self._value = value
        self._index = State(initialValue: values.firstIndex(of: value.wrappedValue) ?? 0)

        self.values = values
        self.upperBound = Float(values.count - 1)
    }

    var body: some View {
        Slider(value: Binding(
            get: { Float(index) },
            set: { index = Int($0); value = values[Int($0)] }
        ), in: 0...upperBound, step: 1)
    }
}

Another approach could look like the following:

struct ContentView: View {
    @State private var sliderValue: Double = 0
    private let values = [100, 500, 600, 1000, 10000]
    
    var body: some View {
        VStack {
            Text("\(values[Int(sliderValue)])")
            
            Slider(value: $sliderValue, in: 0.0...Double(values.count - 1), step: 1)
        }
    }
}

Result:
enter image description here

Related