SwiftUI: How can I change the range from a Slider?

Viewed 728

I would like to create two horizontal Slider. One Slider has a range from 21 to 90 but from 50 the Slider should go in "10 steps". E.g. 21,22,23,...,50,60,70,80,90. The other Slider should be able to display the following double numbers: 1.2, 1.3, 1.4, 1.5, 1.6

I wrote following function:

 struct SliderOne: View {
    @State var valueArray : [Int] = []
    
    var body: some View {
        Text("Placeholder")
    }
    func initPickerIndex(){
        
        valueArray = []
        
        for index1 in 21..<50 {
            valueArray.append(index1)
        }
                   
        for index2 in 1...5 {
            valueArray.append(40 + index2 * 10)
        }
    }
}

Can I use this?

2 Answers

You can create a slider binding manager observable object and add an on change method to observe the slider value. If it goes above 50 just subtract its value truncating the remainder dividing by 10:

struct ContentView: View {
    @ObservedObject var sliderBindingManager = SliderBindingManager(value: 21)
    @State var value1: Int = 21
    @State var value2: Double = 1.2
    var body: some View {
        Slider(value: $sliderBindingManager.value, in: 21...90, step: 1)
        .onChange(of: sliderBindingManager.value) {
            if $0 > 50 {
                sliderBindingManager.value = ($0 / 10).rounded(.toNearestOrEven) * 10
            }
            value1 = Int(sliderBindingManager.value)
        }
        Text("\(value1)")
        Slider(value: $value2, in: 1.2...1.6, step: 0.1)
        Text("\(value2, specifier: "%.1f")")
    }
}

class SliderBindingManager: ObservableObject {
    @Published var value: Double
    init(value: Double) { self.value = value }
}

One possible solution would be changing the step value of the Slider depending on the actual value. However, if you start by 21 you will only get 51, 61, 71 as value ...

struct ContentView: View {
    @State var value = 22.0
    
    var steps : Double {
        value >= 50.0 ? 10.0 : 1.0
    }

    var body: some View {
        Slider(value: $value, in: 21...90, step: steps)
        Text("\(value)")
    }

}
Related