SwiftUI 提供了一套强大的属性包装器,帮助管理状态和数据流。以下是这几种属性包装器的定义和用法。
- @State 和 @Binding:
• @State
@State 是一个属性包装器,用于在 SwiftUI 视图中声明本地状态。当 @State 变量的值改变时,它将使视图失效,并促使视图重新渲染。它通常用于简单的本地组件状态,这些状态不需要共享给其他视图。
例如:
import SwiftUI
struct Content: View {
@State private var isToggled = false
var body: some View {
Toggle("Switch", isOn: $isToggled)
}
}
• @Binding
@Binding 是一个属性包装器,它提供了对一个 @State 属性的引用,或者其它 @Binding 属性的双向绑定。它允许不同的视图共享对同一状态的访问,并能相互更新状态。
例如,使用 @Binding 将状态传递到子视图:
import SwiftUI
struct Content: View {
@State private var isToggled = false
var body: some View {
ChildView(isToggled: $isToggled)
}
}
struct ChildView: View {
@Binding var isToggled: Bool
var body: some View {
Toggle("Switch", isOn: $isToggled)
}
}
- @ObservableObject 和 @ObservedObject:
• @ObservableObject
这是一个协议,当遵从该协议的类的某些属性被标记为 @Published 时,这些属性在发生变化会通知其订阅者。通常用于定义外部的数据模型或状态,这些模型或状态将被多个视图访问和修改。
import Combine
import SwiftUI
class MyModel: ObservableObject {
@Published var isToggled = false
}
struct Content: View {
@ObservedObject var model = MyModel()
var body: some View {
Toggle("Switch", isOn: $model.isToggled)
}
}
• @ObservedObject
这个属性包装器用于声明一个视图要观察的 ObservableObject 实例。当这个实例的 @Published 属性发生变化时,它会重新渲染视图。
- @EnvironmentObject:
@EnvironmentObject 是一个属性包装器,用于从环境中获取一个由某个父视图提供的 ObservableObject 实例。这对于跨多个视图共享数据模型非常有用,不必显式地将模型一层一层传递下去。
例如,在根视图中提供环境对象,并在子视图中访问它:
import Combine
import SwiftUI
class SharedModel: ObservableObject {
@Published var isToggled = false
}
struct Content: View {
@StateObject var model = SharedModel()
var body: some View {
ChildView()
.environmentObject(model)
}
}
struct ChildView: View {
@EnvironmentObject var model: SharedModel
var body: some View {
Toggle("Switch", isOn: $model.isToggled)
}
}
使用 @EnvironmentObject 之前,需要确保在视图层级中的某个点已经往环境中注入了对象,通常是在视图树的顶层进行。如果在环境中找不到相应的对象,那么试图访问 @EnvironmentObject 会导致运行时错误。