xcode SwiftUI:如何使用Thumb移动滑块值

qlckcl4x  于 2023-08-07  发布在  Swift
关注(0)|答案(3)|浏览(117)

我想在SwiftUI中创建带有Value标签的滑块。
我写了下面的代码。

struct SliderView: View {
    @State private var speed = 50.0
    var minValue: Double = 1
    var maxValue: Double = 100
    var body: some View {
        VStack {
            Text("\(speed,specifier: "%.f")")
                .foregroundColor(.blue)

            Slider(
                value: $speed,
                in: minValue...maxValue,
                step: 1
            ) {
                Text("Speed")
            } minimumValueLabel: {
                Text("\(minValue,specifier: "%.f")")
            } maximumValueLabel: {
                Text("\(maxValue,specifier: "%.f")")
            }

        }.padding()
    }
}

字符串
但我想用滑块移动值标签。
我找不到任何属性来设置.frameY值。

问题

如何移动滑块值标签与拇指和移动标签值与拇指的变化。


的数据



jogvjijk

jogvjijk1#

这里的问题是,我们不能访问nob的大小和位置(这是私有的),只能引用范围和当前值,这会导致滑块的nob和hover值之间的一些不对齐。
无论如何,这里是使用对准引导件的可能方法。调整到我留给你的最大尺寸。
已测试Xcode 13.4 / iOS 15.5
x1c 0d1x的数据

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

wgmfuz8q

wgmfuz8q2#

首先你需要读取Slider的宽度,为此你需要一个GeometryReader。使用Slider的当前值,您可以近似拇指的位置。然后你偏移你的Text

struct SliderView: View {
    @State private var speed = 50.0
    var minValue: Double = 1
    var maxValue: Double = 100
    @State var width: CGFloat = 0
    var body: some View {
        VStack {
            Text("\(speed,specifier: "%.f")")
                .foregroundColor(.blue)
                .offset(x: width*speed/100)
            GeometryReader { proxy in
                Slider(
                    value: $speed,
                    in: minValue...maxValue,
                    step: 1
                ) {
                    Text("Speed")
                } minimumValueLabel: {
                    Text("\(minValue,specifier: "%.f")")
                } maximumValueLabel: {
                    Text("\(maxValue,specifier: "%.f")")
                }.onAppear {
                    self.width = proxy.frame(in: .global).width
                }
            }
        }.padding()
    }
}

字符串

laik7k3q

laik7k3q3#

我试过@AsperiAnswer,他做得很好,只是需要一些更新:

问题:

1.一切都很好,直到你的minValue是1。但如果minValue大于1,则浮动标签的位置不同。

更新代码:

struct SliderView: View {
    @State var speed: Double
    var minValue: Double = 50
    var maxValue: Double = 100
    init(minVal: Double, maxVal: Double) {
        self.minValue = minVal
        self.maxValue = maxVal
        self.speed = minVal
    }
    
    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
                    VStack {
                    Text("\(speed,specifier: "%.f")").foregroundColor(.blue)
                        .alignmentGuide(HorizontalAlignment.leading) {
                            print("Hii \(speed) $0.width: \($0.width)")
                            return $0[HorizontalAlignment.leading] - (gp.size.width - $0.width) * (speed - minValue) / ( maxValue - minValue)
                        }
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
                }, alignment: .top)
            Text("\(maxValue,specifier: "%.f")")
        }
        .padding()
    }
}

字符串

用法:

SliderView(minVal: 0, maxVal: 100)

相关问题