@State
- 作用场景:
- 用于在视图内部管理简单的、独立的状态。当状态发生变化时,SwiftUI会自动重新渲染包含该状态的视图。比如一个切换开关的状态、一个文本输入框的内容等在单个视图内维护的状态。
- 原理:
- SwiftUI通过结构体的属性包装器实现。当使用
@State
修饰的属性值改变时,SwiftUI会检测到这个变化,并标记包含该状态的视图需要重新渲染。它会保存状态的旧值和新值,以便比较和决定是否需要重新渲染视图。
- 示例代码:
import SwiftUI
struct ContentView: View {
@State private var isToggleOn = false
var body: some View {
VStack {
Toggle("Toggle", isOn: $isToggleOn)
Text(isToggleOn? "Toggle is on" : "Toggle is off")
}
}
}
@Binding
- 作用场景:
- 用于将一个状态值传递到子视图中,使得子视图可以修改该状态,并且这种修改会反映到父视图。常用于将父视图的状态传递给子视图,以便子视图对状态进行操作,例如在一个自定义的按钮组件中,通过
@Binding
修改父视图中的某个布尔值来控制按钮的禁用状态。
- 原理:
@Binding
本质上是对状态值的引用。它通过$
符号来获取对状态的绑定,这样子视图对绑定值的修改会直接影响到原始状态值。SwiftUI利用这种引用关系来保持状态在不同视图间的一致性。
- 示例代码:
import SwiftUI
struct ChildView: View {
@Binding var isButtonTapped: Bool
var body: some View {
Button("Tap me") {
isButtonTapped.toggle()
}
}
}
struct ParentView: View {
@State private var buttonTapped = false
var body: some View {
VStack {
ChildView(isButtonTapped: $buttonTapped)
Text(buttonTapped? "Button has been tapped" : "Button has not been tapped")
}
}
}
区别
- 作用范围:
@State
主要用于单个视图内部管理状态,状态是视图私有的。
@Binding
用于在不同视图之间共享状态,允许子视图修改父视图的状态。
- 声明方式:
@State
声明时直接修饰属性,如@State private var value = 0
。
@Binding
通常在子视图中声明,并且通过传入父视图状态的绑定来初始化,如@Binding var value: Int
,在父视图中使用$
符号传递,如ChildView(value: $parentValue)
。
- 数据所有权:
@State
拥有自己管理的数据。
@Binding
不拥有数据,只是提供对外部数据的引用。