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 TextFieldStyle
s 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
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
How to Handle Hash Collisions for Dictionaries in Swift
Is There a Daylight Savings Check in Swift
How to Call the More Specific Method of Overloading
Getting a Let Value Outside a Function
Compare Three Values for Equality
Nothing Prints Out in the Console in Command Line Tool Xcode
How to Hide Status Bar and Navigation Bar When Tap Device
Xcode 12 Beta and iOS 14: Weird Console Logs "Objc[5551]: Class ... Is Implemented in Both"
How to Create an Array with Incremented Values in Swift
Swift 2: !, ? -" Value of Optional Type "..." Not Unwrapped"
What Would Be a Proper Storyboard Example of Combining Nav Bars and Tab Bars in One App
Animating a Navigation Bar Color
Swift Mutable Set: Duplicate Element Found
Hot to Decode JSON Data That Could and Array or a Single Element in Swift