我来这里的主要目的是深入定制Stepper组件,以下是我的建议:
我进行了一些搜索,并在https://www.hackingwithswift.com/forums/100-days-of-swiftui/custom-stepper-view/13742上找到了一个不错的提示。
我稍微改进了一下,代码如下。
以下是几点注意事项:
- 使用Double类型时需要小心,添加0.1 20次并不能得到2作为上限(最好使用Int类型,必要时替换Double)
- 我们也可以自定义图标,但不能用于类似Apple Stepper的组件。
编码逻辑:使用两个按钮,如果在范围内,则向上/向下移动,绑定将传播到主视图。
import SwiftUI
typealias CallBack = ( ()->() )?
struct StepperColors{
let leftBtnColor: Color
let rightBtnColor: Color
let backgroundColor: Color
}
struct ColoredStepper: View {
internal init(
value: Binding<Double>,
range: ClosedRange<Double>, step: Double,
onIncrement: CallBack, onDecrement: CallBack,
stepperColors: StepperColors) {
_value = value
self.range = range
self.step = step
self.onIncrement = onIncrement
self.onDecrement = onDecrement
self.stepperColors = stepperColors
}
@Binding private var value: Double
private let range: ClosedRange<Double>
private let step: Double
private let onIncrement: CallBack
private let onDecrement: CallBack
private let stepperColors: StepperColors
private func checkValue(){
if value < range.lowerBound {
value = range.lowerBound
} else if value > range.upperBound {
value = range.upperBound
}
}
var body: some View {
HStack {
Button {
decrement()
} label: {
Image(systemName: "minus")
.frame(width: 38, height: 35)
}
.foregroundColor(stepperColors.leftBtnColor)
.background(stepperColors.backgroundColor)
Spacer().frame(width: 2)
Button {
increment()
} label: {
Image(systemName: "plus")
.frame(width: 44, height: 35)
}
.foregroundColor(stepperColors.rightBtnColor)
.background(stepperColors.backgroundColor)
}
.clipShape(RoundedRectangle(cornerRadius: 8))
.onAppear(perform: checkValue)
}
func decrement() {
if value >= range.lowerBound + step {
value -= step
onDecrement?()
}
}
func increment() {
if value + step <= range.upperBound {
value += step
onIncrement?()
}
}
}
struct ContentView: View {
@State private var value = 0.1
private let stepperColors = StepperColors(leftBtnColor: .red, rightBtnColor: .green, backgroundColor: .white)
var body: some View {
VStack{
ColoredStepper( value: $value, range: 1.0...2.01, step: 0.1,
onIncrement: { print("Incremented") },
onDecrement: { print("Decremented")},
stepperColors: stepperColors )
let text = "\(value.formatted())"
Text(text)
Spacer()
}
}
}
Text
元素添加.background
吗?有点烦人的是,父容器上的修饰符也会影响子元素,但根据SwiftUI教程,预期您会执行像添加修饰符以取消子元素上的动画等操作。 - Rickard Elimää