SwiftUI Slider's label visibility
Asked Answered
T

4

10

Under what circumstances SwiftUI Slider's label is visible? Slider inits can take label arguments, but I don't understand what this label is for?

 struct ContentView: View {
    @State private var slVal: CGFloat = -20
    var body: some View {
        Slider(value: $slVal, in: -40...40, minimumValueLabel: Text("-40"), maximumValueLabel: Text("40")) {
            Text("Invisible text") // This view is not visible 
        }
        .padding()
    }
 }

Putting Slider inside Form doesn't make label appear. I know that DatePicker's label is displayed or not depending on .labelsHidden() modifier and also on DatePickerStyle applied by .datePickerStyle() modifier. Is there something similar with Slider?

Tinkling answered 13/11, 2020 at 11:45 Comment(0)
E
8

It is long known bug in SwiftUI.

Here is possible workaround. Prepared with Xcode 12.1 / iOS 14.1 (backward compatible with SwiftUI 1.0)

demo

struct ContentView: View {
    @State private var slVal: CGFloat = -20
    var body: some View {
        HStack {
            Text("Invisible text")
            Slider(value: $slVal, in: -40...40, minimumValueLabel: Text("-40"), maximumValueLabel: Text("40")) {
                EmptyView()
            }
        }
        .padding()
    }
}
Etra answered 13/11, 2020 at 12:55 Comment(1)
Looks more like an undone thing rather than a bold bug.Tinkling
D
1

Slightly modified version of workaround from @Asperi:

func slider<V, C>(
    value: Binding<V>,
    in bounds: ClosedRange<V> = 0...1,
    label: () -> C,
    onEditingChanged: @escaping (Bool) -> Void = { _ in }
) -> some View where V : BinaryFloatingPoint,
                     V.Stride : BinaryFloatingPoint,
                     C: View {
    HStack {
        label()
        Slider(
            value: value,
            in: bounds,
            onEditingChanged: onEditingChanged,
            label: { EmptyView() }
        )
    }
}

and usage:

slider(value: $aValue, in: -1...1, label: {
    Text("aValue")
})
Diode answered 8/12, 2020 at 9:39 Comment(1)
It can be handy, but I hope they will just fix label at some point of future along with giving some styles to sliders as it is done for Buttons, Pickers, Text Fields, Toggles and so on. Maybe a convenience init (not a free function) would be more appropriate here?Tinkling
V
1

According to official documentation not all slider styles show the labels, but even in those cases, SwiftUI uses the label for accessibility (for example VoiceOver).

Versatile answered 21/8, 2021 at 17:29 Comment(1)
I wonder what slider styles display labels? I tried to create a macOS toolbar with a slider, and its label is hidden.Unknit
K
1

Slider does not seem to show label in compact size class. I usually make an extension like this

extension Slider {
    func inLabeled(label: Text) -> some View {
#if os(OSX)
        self
#else
        LabeledContent {
            self
        } label: {
            label
        }
#endif
    }
}

then apply it to Slider

Slider(value: $speechManager.rate, in: min ... max) {
    Text("Rate")
}
.inLabeled(label: Text("Rate"))
Kristopherkristos answered 8/7, 2023 at 16:20 Comment(2)
Interesting approach. Won't it be labeled twice for regular size classes this way? On iPads for example. We kind of duplicating labels here, don't we?Tinkling
Ja, you can tweak this to your need, just an ideaKristopherkristos

© 2022 - 2024 — McMap. All rights reserved.