如何使用 SwiftUI 创建带有刻度线的滑块?

问题描述 投票:0回答:2

使用 SwiftUI,我想创建一个最小/最大范围为 5-20 的滑块,用户可以在其中滑动并向上移动 5。开箱即用的滑块看起来非常“平坦”/平滑。有没有一种方法可以添加所述刻度线,以便滑块看起来像“捕捉”到刻度线?

如果滑块被认为不是实现该效果的正确方法,我愿意接受其他选项。

ios swift swiftui
2个回答
7
投票

滑块有很多初始化选项,其中一些包含“step”参数,用于创建捕捉效果。它的边缘没有可见的刻度线,但您可以在旁边手动创建它。

import SwiftUI

struct SliderView: View {
    
    @State var value: CGFloat = 10
    let min: CGFloat = 5
    let max: CGFloat = 20
    let step: CGFloat = 5
    
    var body: some View {
        VStack {
            Text(formated(value: value))
            
            Slider(
                value: $value,
                in: min...max,
                step: step,
                minimumValueLabel: Text(formated(value: min)),
                maximumValueLabel: Text(formated(value: max)),
                label: { })

            VStack(spacing: 0) {
                Slider(
                    value: $value,
                    in: min...max,
                    step: step)
                    .accentColor(.red)
                
                HStack(spacing: 0) {
                    let count: Int = Int((max / step))
                    ForEach(0..<count) { index in
                        VStack {
                            Text("I")
                            Text("\(index * Int(step) + Int(min))")
                        }
                        .offset(x:
                          index == 1 ? 5 :
                          index == 2 ? 4 :
                          0
                        )
                        if index != (count - 1) {
                            Spacer()
                        }
                    }
                }
                .padding(.horizontal, 8)
            }
            .padding()
        }
        .padding()
    }
    
    func formated(value: CGFloat) -> String {
        return String(format: "%.0f", value)
    }
    
}

0
投票

添加刻度线的一种简单方法是将它们显示在

HStack
后面的背景中的
Slider
中,每个刻度线之间有一个
Spacer

唯一的复杂之处是滑块按钮停止时其边缘与滑块凹槽的边缘对齐,它不会越过凹槽的末端。因此需要在

HStack
上添加水平内边距,以考虑滑块按钮的宽度:

Slider(value: $value, in: 1...5, step: 1) {}
    .frame(maxWidth: 300)
    .background {
        HStack(spacing: 0) {
            ForEach(1...5, id: \.self) { i in
                Rectangle()
                    .foregroundStyle(.pink)
                    .frame(width: 2)
                    .padding(.vertical, 5)
                if i < 5 {
                    Spacer()
                }
            }
        }
        .padding(.horizontal, 12)
    }

Screenshot

有关将标签与刻度线对齐的方法,请参阅如何在 HStack 中间隔不同宽度的文本,以便文本的中心在 SwiftUI 中正确定位的答案。

© www.soinside.com 2019 - 2024. All rights reserved.