How customise Slider blue line in SwiftUI?
Asked Answered
M

6

26

Like in UISlider

let slider = UISlider()

slider.minimumTrackTintColor = .red
Methinks answered 18/7, 2019 at 19:51 Comment(1)
I don't understand the close votes on this question. It's a perfectly reasonable question.Austroasiatic
A
13

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.

Austroasiatic answered 18/7, 2019 at 22:0 Comment(2)
.accentColor(.red)Xanthin
For TextFieldStyle, the private API is struct MyTextFieldStyle: TextFieldStyle { func _body(configuration: TextField<_Label>) -> some View { configuration.foregroundColor(.red) } }. Source (and thanks!): swiftwithmajid.com/2020/02/26/textfield-in-swiftui. Reminder: this is the private/internal/undocumented API, liable to break or cause other issues in the future.Unstable
M
40

As pointed out in other answers you have limited ability to customize a Slider in SwiftUI. You can change the .accentColor(.red) but that only changes the minimumTrackTintColor.

Example of a Slider with .accentColor(.red)

enter image description here

Additionally, you can't change other things like thumbTintColor. If you want more customization than just minimumTrackTintColor that you have no choice but to use a UISlider in SwiftUI as rob mayoff stated.

Here is some code on how you can use a UISlider in SwiftUI

struct SwiftUISlider: UIViewRepresentable {

  final class Coordinator: NSObject {
    // The class property value is a binding: It’s a reference to the SwiftUISlider
    // value, which receives a reference to a @State variable value in ContentView.
    var value: Binding<Double>

    // Create the binding when you initialize the Coordinator
    init(value: Binding<Double>) {
      self.value = value
    }

    // Create a valueChanged(_:) action
    @objc func valueChanged(_ sender: UISlider) {
      self.value.wrappedValue = Double(sender.value)
    }
  }

  var thumbColor: UIColor = .white
  var minTrackColor: UIColor?
  var maxTrackColor: UIColor?

  @Binding var value: Double

  func makeUIView(context: Context) -> UISlider {
    let slider = UISlider(frame: .zero)
    slider.thumbTintColor = thumbColor
    slider.minimumTrackTintColor = minTrackColor
    slider.maximumTrackTintColor = maxTrackColor
    slider.value = Float(value)

    slider.addTarget(
      context.coordinator,
      action: #selector(Coordinator.valueChanged(_:)),
      for: .valueChanged
    )

    return slider
  }

  func updateUIView(_ uiView: UISlider, context: Context) {
    // Coordinating data between UIView and SwiftUI view
    uiView.value = Float(self.value)
  }

  func makeCoordinator() -> SwiftUISlider.Coordinator {
    Coordinator(value: $value)
  }
}

#if DEBUG
struct SwiftUISlider_Previews: PreviewProvider {
  static var previews: some View {
    SwiftUISlider(
      thumbColor: .white,
      minTrackColor: .blue,
      maxTrackColor: .green,
      value: .constant(0.5)
    )
  }
}
#endif

Then you can use this slider in your ContentView like this:

struct ContentView: View {
  @State var sliderValue: Double = 0.5

  var body: some View {
    VStack {
      Text("SliderValue: \(sliderValue)")
      // Slider(value: $sliderValue).accentColor(.red).padding(.horizontal)

      SwiftUISlider(
        thumbColor: .green,
        minTrackColor: .red,
        maxTrackColor: .blue,
        value: $sliderValue
      ).padding(.horizontal)
    }
  }
}

Example:

enter image description here

Link to full project

Macroclimate answered 16/11, 2019 at 19:26 Comment(2)
.accentColor(.red) has no effect in my macOS project (Xcode 12.2 beta 4, macOS 11 RC).Tatianna
How do i change the height of the slider line?Wend
X
15
.accentColor(.red)

This will work on iOS and Mac Catalyst. Check out customizable sliders example here

Xanthin answered 26/8, 2019 at 21:20 Comment(1)
Project will find now under these link: github.com/spacenation/swiftui-slidersAnima
A
13

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.

Austroasiatic answered 18/7, 2019 at 22:0 Comment(2)
.accentColor(.red)Xanthin
For TextFieldStyle, the private API is struct MyTextFieldStyle: TextFieldStyle { func _body(configuration: TextField<_Label>) -> some View { configuration.foregroundColor(.red) } }. Source (and thanks!): swiftwithmajid.com/2020/02/26/textfield-in-swiftui. Reminder: this is the private/internal/undocumented API, liable to break or cause other issues in the future.Unstable
S
4

If the bright white slider handle grates on your dark mode design, you can use .label color and .softLight to tell it to simmer down. It looks good only in grayscale, unless you can figure out the blend modes and hue rotation.

The best looking result would be from an overlaid shaped with .blendMode(.sourceAtop)... but that blocks interaction, sadly.


@Environment(\.colorScheme) var colorScheme

var body: some View {

        let hackySliderBGColor: Color = colorScheme == .dark ? Color(.secondarySystemBackground) : Color(.systemBackground)
        let hackySliderAccentColor: Color = colorScheme == .dark ? Color(.label) : Color(.systemGray2)
        let hackySliderBlendMode: BlendMode = colorScheme == .dark ? .softLight : .multiply

...

    ZStack {
            Rectangle()
            .foregroundColor(hackySliderBGColor)

// This second Rect prevents a white sliver if slider is at max value.
             .overlay(Rectangle()
                  .foregroundColor(hackySliderBGColor)
                  .offset(x: 5)
             )

            Slider(value: $pointsToScoreLimit, 
                   in: themin...themax, step: 5)
            .accentColor(hackySliderAccentColor)
            .blendMode(hackySliderBlendMode)
    }


Example: 1 2

Senile answered 4/7, 2020 at 17:10 Comment(0)
I
3

You can change the maximum track color using ZStack like this

var body: some View {
  VStack {
    Spacer()
    Image("Fun").resizable().frame(width: 200, height: 200, alignment: .center).cornerRadius(20)
    ZStack {
      Rectangle()
        .frame(height: 2)
        .foregroundColor(.yellow).frame(width: UIScreen.main.bounds.width - 150)
      Slider(value: $sliderval, in: 0...timeSlider_maximumValue, label: {Text("PLayer")}, minimumValueLabel: {Text("\(timeSlider_minimumValue)")}, maximumValueLabel: {Text("\(timeSlider_maximumValuetext)")}) { success in
        SilderTap()
      }.padding(.horizontal).tint(.green).foregroundColor(.white)
    }
  }
}

enter image description here

Islington answered 6/2, 2023 at 17:41 Comment(0)
R
2

So I tried to use .accentColor(.red) without success, so I noticed that for newer versions one has to use .tint(.red) to make the changes visible.

Hope this helps.

Repute answered 19/5, 2022 at 11:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.