@State
@State
属性包装器在视图里面使用,允许视图对@State
的属性进行响应。@State
是视图本身初始化的属性。它不能获取另一个对象的@State
属性的值。
less
struct StateExample: View {
@State private var intValue = 0
@State private var modelObject = MyModelObject()
var body: some View {
VStack {
Text("intValue equals (intValue)")
Button("Increment") {
intValue += 1
}
}
}
}
SwiftUI会存储@State
属性的值,并在视图重新渲染期间保存它的值。这使得@State
非常适合用于视图本身的状态管理,因此在视图实例刷新(重构)的时候会保留状态。
请注意:将视图的@State
属性标记private
,从而防止任何外部修改视图的@State
属性。
@State
使用的注意事项:
- 属性的类型通常是值类型(
struct
或enum
)。 - 在iOS 17+时可以包装一个
@Observable
的对象。 - 视图本身创建(并拥有)的属性。
- 需要响应某个属性发生的改变。
请注意,在引用类型 (
class
) 上使用@State
,但更改实例本身的属性不会更新。即使您更改的属性是@Published
。在 iOS 17+ 上,用@Observable
注释的对象可以使用@State
并且会起到更新的作用。该@Observable
宏使用一种特殊的机制将模型更改传达给视图。
@Binding
@Binding
属性包装器用于视图属性的传递。接收绑定的视图能够读取绑定的属性,响应父视图所做的改变,并且拥有对该属性的读写。
接收@Binding
属性的值并且点击按钮导致intValue改变的例子:
swift
struct StateView: View {
@State private var intValue = 0
var body: some View {
VStack {
Text("intValue equals (intValue)")
BindingView(intValue: $intValue)
}
}
}
struct BindingView: View {
@Binding var intValue: Int
var body: some View {
Button("Increment") {
intValue += 1
}
}
}
@State
属性的值是可以传递给子视图,以便它们可以通过绑定修改属性而不是直接修改属性。在@Binding
内部,当您的视图被丢弃时,值不会保留。因为@Binding
总是由外部传值的。@State
与 @Binding
的区别就是当视图被丢弃并重新创建以进行新渲染时,其值仍然存在。
@Binding
使用的注意事项:
- 需要对父视图拥有的属性进行读写。
- 属性是值类型(
struct
或enum
)。(可以是引用类型 (class
),但它并不常见。) - 不拥有属性的值状态(它由父视图提供)。