How Customise Slider Blue Line in Swiftui

How customise Slider blue line in SwiftUI?

As of Apple's 2021 platforms, you can use the tint modifier to change the color of the track to the left of the slider knob. Beyond that, SwiftUI's Slider doesn't let you customize its appearance.

If you need more customization, then for now your only option is to create a UISlider and wrap it in a UIViewRepresentable. Work through the “Interfacing with UIKit” tutorial and watch WWDC 2019 Session 231: Integrating SwiftUI to learn how to use UIViewRepresentable.

The Slider documentation formerly mentioned a type named SliderStyle, but there is no documentation for SliderStyle and the type is not actually defined in the public interface of the SwiftUI framework as of Xcode 11 beta 4. It is possible that it will appear in a later release. It is also possible that we will have to wait for a future (after 13) version of SwiftUI for this ability.

If SliderStyle does appear, it might allow you to customize the appearance of a Slider in the same way that ButtonStyle lets you customize the appearance of Button—by assuming total responsibility for drawing it. So you might want to look for ButtonStyle tutorials on the net if you want to get a head start.

But SliderStyle might end up being more like TextFieldStyle. Apple provides a small number of TextFieldStyles for you to choose from, but you cannot define your own.

Changing Slider thumb in SwiftUI

You can do this with SwiftUI-Introspect.

You are basically just accessing the underlying UISlider from SwiftUI's Slider, and then setting it there. This is much easier than creating a custom slider or making a representable.

Code:

struct ContentView: View {
@State private var value: Double = 0

var body: some View {
Slider(value: $value)
.introspectSlider { slider in
slider.setThumbImage(UIImage(named: "Play_black"), for: .normal)
}
}
}

Result (temporary image):


How to create custom slider by using SwiftUI?

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)
...

SwiftUI: How to move Slider Value with Thumb

The problem here is that we do not have access to nob size and positioning (which are private) and refer only to range and current value, and this leads to some misalignment between slider's nob and hover value.

Anyway here is possible approach using alignment guide. Tuning to nob size I leave for you.

Tested with Xcode 13.4 / iOS 15.5

demo

struct SliderView: View {
@State private var speed = 50.0

var minValue: Double = 1
var maxValue: Double = 100

var body: some View {
HStack {
Text("\(minValue,specifier: "%.f")")
Slider(value: $speed, in: minValue...maxValue, step: 1)
.alignmentGuide(VerticalAlignment.center) { $0[VerticalAlignment.center]}
.padding(.top)
.overlay(GeometryReader { gp in
Text("\(speed,specifier: "%.f")").foregroundColor(.blue)
.alignmentGuide(HorizontalAlignment.leading) {
$0[HorizontalAlignment.leading] - (gp.size.width - $0.width) * speed / ( maxValue - minValue)
}
.frame(maxWidth: .infinity, alignment: .leading)
}, alignment: .top)
Text("\(maxValue,specifier: "%.f")")
}
.padding()
}
}

Test module on GitHub

How does one change the position of a Slider in SwiftUI?

example:

struct ContentView: View {

@State var number : Float

var body: some View {
VStack {
Slider(value: $number, in: 1...100)
.padding()
Text("You've selected \(Int(number))")
}.onAppear() {
self.number = 30
}
}
}

Object Color not Updating when Changing Custom Slider Value in SwiftUI

Your problem is that the redValue being set by your slider is a value in the range 0.0...100.0, but you need a value in the range 0.0...1.0 when setting the color of the Rectangle:

Rectangle()
.foregroundColor(Color(red: redValue/100, green: greenValue, blue: blueValue, opacity: 1.0))
.cornerRadius(10)

Changing the thumb image of the slider conditionally in SwiftUI

You can use slider method,

setThumbImage(image, for: .normal)
setThumbImage(image, for: . highlighted)

And as per your requirement if you want to change image on value change you need to add your code like (code is from your attached link sample),

@objc func valueChanged(_ sender: UISlider) {
self.value.wrappedValue = Double(sender.value)
let arra: [UIImage?] = [UIImage(systemName: "heart"), UIImage(systemName: "pencil"), UIImage(systemName: "trash")]

sender.setThumbImage(arra.randomElement() as? UIImage, for: .normal)
sender.setThumbImage(arra.randomElement() as? UIImage, for: .highlighted)
}


Related Topics



Leave a reply



Submit