Search code examples
iosswiftuser-interfaceswiftuiios13

How to create custom slider by using SwiftUI?


I am able to create a Slider by using SwiftUI but I am not able to change the style of the slider as shown in the image(below).

Problem: I am not able to find any option in SwiftUI to change the slider style.

Note: I want to create this by using SwiftUI only. I already created this slider in Swift by using "https://github.com/daprice/iOS-Tactile-Slider"

I have tried following but it's not the solution :

1. Slider(value: .constant(0.3)).accentColor(Color.white)

2. Slider(value: $age, in: 18...20, step: 1, minimumValueLabel: Text("18"), maximumValueLabel: Text("20")) { Text("") }

3. Slider(value: $age, in: 18...20, step: 1, minimumValueLabel: Image(systemName: "18.circle"), maximumValueLabel: Image(systemName: "20.circle")) { Text("") }

How can I create a slider with the style as shown in the image using SwiftUI only?

enter image description here


Solution

  • As it turned out for me accent color is depending on the context, as well as the frame, so we don't need to handle that.

    As far as the control goes I made a really dummy and simple example. Please do not consider this as a solution, rather a starter.

    struct CustomView: View {
    
        @Binding var percentage: Float // or some value binded
    
        var body: some View {
            GeometryReader { geometry in
                // TODO: - there might be a need for horizontal and vertical alignments
                ZStack(alignment: .leading) {
                    Rectangle()
                        .foregroundColor(.gray)
                    Rectangle()
                        .foregroundColor(.accentColor)
                        .frame(width: geometry.size.width * CGFloat(self.percentage / 100))
                }
                .cornerRadius(12)
                .gesture(DragGesture(minimumDistance: 0)
                    .onChanged({ value in
                        // TODO: - maybe use other logic here
                        self.percentage = min(max(0, Float(value.location.x / geometry.size.width * 100)), 100)
                    }))
            }
        }
    }
    

    You can use it like

        @State var percentage: Float = 50
    
        ...
        var body: some View {
        ...
                CustomView(percentage: $percentage)
                    .accentColor(.red)
                    .frame(width: 200, height: 44)
        ...