那么在下面的代码中:
struct ContentView: View {
@State private var blurAmount = 0.0 {
didSet {
print("Hey")
}
}
init() {
_blurAmount = State(wrappedValue: 3.3)
}
var body: some View {
Button("Tap me") {
// this line gives an error saying Cannot assign to property: 'self' is immutable
_blurAmount = State(wrappedValue: 3.3)
}
}
}
我知道_blurAmount
是State<Double>
结构体本身,_blurAmount = State(wrappedValue: 3.3)
正在创建一个struct的新实例。通常会在init()中使用。
我想要的结果是打印"每当我点击按钮。这样我就可以让_blurAmount = State(wrappedValue: 3.3)
创建一个State的新实例。
但是为什么我们不能在视图中创建Struct的新实例呢?
这实际上与State本身无关。让我们举一个更简单的例子!
struct ContentView: View {
var greeting = "howdy"
init() {
greeting = "hello"
}
var body: some View {
Button("Tap me") {
greeting = "hey there" // same error
}
}
}
这就是Swift的工作方式。ContentView是一个结构体。结构体在原地是不可变的。因此,你可以初始化greeting
,但是一旦初始化结束,你不能修改它,因为那将是一个结构体ContentView的突变,你不能这样做。
这个原则实际上是SwiftUI的关键原则之一。这正是@State
存在的原因;@State
变量是可变的,因为它(如您所说)在幕后单独存在。这里的想法是强迫您以清晰和可控的方式表达视图的可变方面。
说了这么多,你可以给你的实际变量赋值,确切地说,因为是一个@State
变量:你可以说blurAmount = 4.4
(或其他)。这是合法的,并且它的工作方式与您期望的一样:
var body: some View {
Button("Tap me") {
blurAmount = 4.4
}
}