# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lochiwei.gitbook.io/ios/custom/control/sliderwithlabel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
