> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/ios/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/ios/custom/control/sliderwithlabel.md).

# SliderWithLabel

[swift](/ios/swift.md)⟩ [custom](/ios/custom.md) ⟩ [control](/ios/custom/control.md) ⟩ <mark style="color:purple;">`SliderWithLabel`</mark>&#x20;

{% hint style="info" %}
可自訂<mark style="color:yellow;">標題</mark>與<mark style="color:yellow;">數值格式</mark>的 [Slider](/ios/swiftui/control/slider.md)。
{% endhint %}

![](/files/ra7kdwEJM1qkcDi0P9nY)

{% tabs %}
{% tab title="💈範例" %}

```swift
// (defaults) in: 0...1, step: nil, specifier: "%.2f"
SliderWithLabel(         
    value: $t            
) { Text("寬度(0-1)：") } // title label

SliderWithLabel(
    value: $m, in: 100...200, step: 1, // step = 1
    specifier: "%.0f"                  // integer
) { Text("音量(0-200)：") }             // title label

SliderWithLabel(
    value: $n, in: 0...100, step: 5,   // step = 5
    specifier: "%.0f"                  // integer
) { Text("音量(0,5...100)：") }
```

{% endtab %}

{% tab title="💾 程式" %}

```swift
import SwiftUI
import GeometryKit

struct SliderWithLabel<
    V: BinaryFloatingPoint & _FormatSpecifiable, 
    TitleLabel: View 
//    ValueLabel: View
>: View where V.Stride: BinaryFloatingPoint {
    
    @Binding var value: V
    
    let `in`: ClosedRange<V>
    let step: V.Stride?
    var min: V { `in`.lowerBound }
    var max: V { `in`.upperBound }
    var t: V { (value - min)/(max - min) }
    
    let specifier: String    // like "%.0f"
    
    /*@ViewBuilder*/ let titleLabel: () -> TitleLabel
    
    let knobWidth: CGFloat = 28
    let yOffset: CGFloat = -16
    
    init(value: Binding<V>, in bounds: ClosedRange<V>, step: V.Stride? = nil, specifier: String = "%.0f", titleLable: @escaping () -> TitleLabel = {Text("Untitled")}){
        self._value = value
        self.in = bounds
        self.step = step
        self.specifier = specifier
        self.titleLabel = titleLable
    }
      
    var body: some View {
        HStack {
            titleLabel()
            sliderWithValueLabel
        }
        .padding(.top, 30)
    }// body
    
    // slider
    @ViewBuilder var slider: some View {
        if let step = step {
            Slider(value: $value, in: `in`, step: step)
        } else {
            Slider(value: $value, in: `in`)
        }
    }
    
    // slider + value label
    var sliderWithValueLabel: some View {
        slider
            .background { 
                GeometryReader { geo in
                    Text("\(value, specifier: specifier)")
                        // ⭐️ position label directly
                        .position(geo.size[CGFloat(t), 0])    // GeometryKit
                        .offset(y: yOffset)           // move upward
                }//GeometryReader
                .padding(.horizontal, knobWidth/2)    // ⭐️ knob half width
            }// slider.background
    }// sliderWithValueLabel
    
}// ValueSlider
```

📁 Examples & Previews

```swift
// value slider example
private struct SliderWithLabelExample: View {
    
    @State var m: CGFloat = 150    // 100, 101 ... 200 (integer)
    @State var t: CGFloat = 0.8    // 0 ... 1          (decimal)
    @State var n: CGFloat = 25     // 0, 5, ... 100    (integer)
    
    var body: some View {
        VStack {
            Spacer()
            Form {
                
                SliderWithLabel(         // in       : 0...1  (default)
                    value: $t            // step     : nil    (default) 
                ) { Text("寬度(0-1)：") } // specifier: "%.2f" (default)
                
                SliderWithLabel(
                    value: $m, in: 100...200, step: 1, // step = 1
                    specifier: "%.0f"                  // integer
                ) { Text("音量(0-200)：") }
                    .frame(maxWidth: 500)
                
                SliderWithLabel(
                    value: $n, in: 0...100, step: 5,   // step = 5
                    specifier: "%.0f"                  // integer
                ) { Text("音量(0,5...100)：") }
                    .accentColor(.red)
                
            }// Form
            Spacer()
        }
    }// body
}// ValueSliderExample

// ------------- Previews --------------

// previews
struct SliderWithLabel_Previews: PreviewProvider {
    static var previews: some View {
        SliderWithLabelExample()
    }
}
```

{% endtab %}

{% tab title="⬆️ 需要" %}

* [GeometryKit](/ios/custom/package/geometrykit.md)：利用 <mark style="color:blue;">`size[x, y]`</mark> 的語法來計算[位置](/ios/swiftui/view/layout/position.md)。
  {% endtab %}

{% tab title="👥 相關" %}

* <mark style="color:purple;">`SliderWithLabel`</mark>：
  * 使用 [＠Binding](/ios/swiftui/view/state/binding/binding.md) 變數。
  * 是一個[自製的](/ios/custom.md) [Slider](/ios/swiftui/control/slider.md)。
* [Slider label position](/ios/swiftui/control/slider/label-position.md)：講解<mark style="color:yellow;">如何擺放數值標籤</mark>的細節。
  {% endtab %}
  {% endtabs %}
