SwiftUI 中的@State、@Bindable和@Binding

原文:https://ichochy.com/posts/swift/20250402.html

在 SwiftUI 中,@State@Bindable 和 @Binding 都用于管理和传递状态,但它们适用于不同的使用场景。


1. @State(本地状态)

@State 用于管理 视图本地的可变状态,该状态只属于当前视图,并且由 SwiftUI 负责存储和更新。

特点:

示例:

struct CounterView: View {
    @State private var count = 0  // 本地状态

    var body: some View {
        VStack {
            Text("计数: \(count)")
            Button("增加") {
                count += 1  // 修改 @State 变量,SwiftUI 重新渲染视图
            }
        }
    }
}

2. @Binding(状态绑定)

@Binding 用于 子视图获取父视图的状态,它本身不存储数据,而是引用 外部的状态(通常是 @State)

特点:

示例:


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 前面要加 $ 取 绑定值,在子视图内部可直接读写该值。


3. @Bindable(可绑定的对象)【iOS 17+

@Bindable 用于绑定 Observable 对象(通常是 ObservableObject),让 SwiftUI 视图可以自动响应对象属性的变化。

特点:

示例(结合 Observable)

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 类属性,适用于复杂数据

使用建议: