使用 SwiftUI,我想创建一个最小/最大范围为 5-20 的滑块,用户可以在其中滑动并向上移动 5。开箱即用的滑块看起来非常“平坦”/平滑。有没有一种方法可以添加所述刻度线,以便滑块看起来像“捕捉”到刻度线?
如果滑块被认为不是实现该效果的正确方法,我愿意接受其他选项。
滑块有很多初始化选项,其中一些包含“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)
}
}
添加刻度线的一种简单方法是将它们显示在
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)
}
有关将标签与刻度线对齐的方法,请参阅如何在 HStack 中间隔不同宽度的文本,以便文本的中心在 SwiftUI 中正确定位的答案。