
























原文:https://ichochy.com/posts/swift/20250402.html
在 SwiftUI 中,@State、@Bindable 和 @Binding 都用于管理和传递状态,但它们适用于不同的使用场景。
@State 用于管理 视图本地的可变状态,该状态只属于当前视图,并且由 SwiftUI 负责存储和更新。
只能用于 结构体(struct)视图,因为 SwiftUI 视图是值类型。
适用于 视图内部的小型状态,如按钮点击状态、输入框文本等。
只能在 当前视图 中使用,不能直接传递给子视图。
struct CounterView: View {
@State private var count = 0 // 本地状态
var body: some View {
VStack {
Text("计数: \(count)")
Button("增加") {
count += 1 // 修改 @State 变量,SwiftUI 重新渲染视图
}
}
}
}
@Binding 用于 子视图获取父视图的状态,它本身不存储数据,而是引用 外部的状态(通常是 @State)。
@Binding 不拥有数据,而是对外部数据的引用。
用于 子视图修改父视图的状态,避免数据复制。
适用于 控制组件、表单、滑块等需要修改外部状态的视图。
struct ParentView: View {
@State private var isOn = false // 本地状态
var body: some View {
ToggleView(isOn: $isOn) // 传递 @Binding
}
}
struct ToggleView: View {
@Binding var isOn: Bool // 绑定外部的状态
var body: some View {
Toggle("开关状态", isOn: $isOn) // 直接修改外部状态
}
}
@Binding 前面要加 $ 取 绑定值,在子视图内部可直接读写该值。
@Bindable 用于绑定 Observable 对象(通常是 ObservableObject),让 SwiftUI 视图可以自动响应对象属性的变化。
作用类似 @Binding,但适用于 类对象(Observable)。
依赖 Observable 协议(iOS 17 引入)。
适用于 需要双向绑定的复杂数据对象。
import SwiftUI
@Observable class UserSettings {
var username: String = "张三"
}
struct ContentView: View {
@State private var settings = UserSettings() // `@State` 管理对象
var body: some View {
EditView(settings: $settings) // 传递 `@Bindable`
}
}
struct EditView: View {
@Bindable var settings: UserSettings // 绑定 Observable 对象
var body: some View {
TextField("用户名", text: $settings.username) // 绑定属性
}
}
这里 @Bindable var settings: UserSettings 允许 EditView 直接修改 settings.username,并且 SwiftUI 会自动更新 ContentView。
| 属性修饰符 | 数据存储 | 作用范围 | 适用场景 |
|---|---|---|---|
| @State | 视图内部 | 仅当前视图 | 视图局部状态 |
| @Binding | 外部状态(引用) | 子视图 | 子视图修改父视图状态 |
| @Bindable | Observable 对象 | 子视图 | 绑定 Observable 类属性,适用于复杂数据 |
使用建议:
简单数据(计数、布尔值):用 @State。
子视图修改父视图的状态:用 @Binding。
对象(类)状态 且 多个视图共享:用 @Bindable(iOS 17+)。
iOS 16 及以下,用 @ObservedObject 代替 @Bindable(结合 ObservableObject)。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。