Stepper

Stepper 在水平方向是扩张型视图,在垂直方向是收缩型视图。

SwiftUI 有两种让用户输入数字的方法,一种是 Stepper :简单的 - 和 + 按钮,可以点击它来选择精确的数字。另一个是 Slider ,它也允许我们从一系列值中进行选择,但不太精确。步进器足够智能,可以处理任何类型的数字类型,因此可以将它们绑定到 Int 、 Double 等,并且它会自动适应。

使用步进器视图时,需要将其绑定到状态属性,通常是数字。但它不一定是数字类型。它可以是任何符合 Stridable 协议的类型。 ( Stride 的意思是“朝一个方向迈出一步;通常是长步”。)符合 Stridable 的类型意味着它具有连续的值,并且可以逐步遍历和测量。


参数: label 标题

label 参数直接写到最前面,不需要参数名。虽然有时候即使看不见,也应该填上,对视障人士可用性有益。

Stepper("What is your age?", value: $stepperValue)

参数: value 双向绑定值

value 参数需要绑定一个状态属性,可以是整数、浮点数

// 绑定一个整数
@State private var stepperValue = 1 

Stepper(value: $stepperValue) {        
	Text("Bound Stepper: \\(stepperValue)")
}

参数:in 范围

in 范围参数可以限制我们想要接受的值。当 Stepper 达到范围限制时,相应的加号或减号按钮将显示为禁用。

Stepper("\\(sleepAmount) hours", value: $stars, in: 1...5) { ... }

参数:step 步长

step 步长参数可以设定每次加减的幅度。

Stepper("\\(sleepAmount) hours", value: $sleepAmount, in: 4...12, step: 0.25)

闭包:label 视图

如果不设置标签文案,可以通过闭包来设置更复杂的 步进器 视图。

Stepper(value: $stepperValue) {        
	VStack {
		Text("增加&减少")
		Text("hahaha")
		Image(systemName: "cloud.heavyrain")
	}
}

闭包:onIncrement、onDecrement

如果希望在点击步进器的加减按钮时执行一个函数。可以通过为 Stepper 添加 onIncrementonDecrement 闭包来实现这一功能。以下是一个示例代码,演示了如何在点击步进器的加减按钮时执行自定义函数:

@State private var stepperValue = 1

    var body: some View {
        VStack {
            Stepper(value: $stepperValue) {
                Text("Bound Stepper: \\(stepperValue)")
            }
            .onIncrement {
                // 在增加时执行的函数
                increaseValue()
            }
            .onDecrement {
                // 在减少时执行的函数
                decreaseValue()
            }
        }
    }

    func increaseValue() {
        stepperValue += 1    // 执行增加数值的操作
    }

    func decreaseValue() {
        stepperValue -= 1    // 执行减少数值的操作
    }
    
    

// 另一个例子:使用 Stepper 控件操纵一个数组
// 在这个示例中,@State属性包装器用于存储一个整数数组,初始值为[0, 1]
// onIncrement 闭包用于在点击增加按钮时向数组中添加一个新的元素,而 onDecrement 闭包用于在点击减少按钮时移除数组中的最后一个元素
@State private var values = [0, 1]

// 这个例子中,数组不需要绑定
Stepper(
		onIncrement: { self.values.append(self.values.count) }, 
		onDecrement: { self.values.removeLast() }
){
		Text("onIncrement and onDecrement") 
}

其他

增加减少都执行同样的函数

还有一种声明 Stepper 的方法,可以不管是增加还是减少,都执行同一个方法。

@State private var numColumns = 3
@State private var gridColumns = Array(repeating: GridItem(.flexible()), count: 3)

Stepper("Set Column", value: $numColumns, in: 1...6, step: 1) { _ in
		gridColumns = Array(repeating: GridItem(.flexible()), count: numColumns)
}

通过判断来限制输入范围

// 方式一:建立属性观察器:確保 maxPriceLevel 的值是在 1 跟 5 之間
@State private var maxPriceLevel = 5 {
    didSet {
        if maxPriceLevel > 5 {
            maxPriceLevel = 5
        }

        if maxPriceLevel < 1 {
            maxPriceLevel = 1
        }
    }
}

// 方式二:在增加减少函数里写判断
Stepper(
	onIncrement: {self.maxPriceLevel += 1
	if self.maxPriceLevel > 5{
		self.maxPriceLevel = 5
	}
}, 
	onDecrement: {self.maxPriceLevel -= 1
	if self.maxPriceLevel < 1{
		self.maxPriceLevel = 1
	}
}
	) {
  Text("Show \\(String(repeating: "$", count: maxPriceLevel)) or below")
}