SwiftUI中如何声明全局@State变量实现多视图数据共享?
实现方案(基于SwiftUI原生数据管理能力)
你的需求最适合用SwiftUI自带的可观察对象体系实现,不需要自定义全局变量,系统会自动处理视图同步刷新逻辑,步骤如下:
第一步:创建全局可观察数据模型
新建一个遵守ObservableObject协议的类,所有需要多视图共享的属性都添加@Published修饰:
import SwiftUI class UserData: ObservableObject { // 属性变化时会自动通知所有监听的视图刷新 @Published var gender: String = "未设置" @Published var weight: Double = 0.0 @Published var qualification: String = "未设置" }
第二步:给视图树注入全局唯一实例
在App根入口初始化一次数据实例,挂载到整个视图树,所有子视图都可以直接访问:
@main struct MyApp: App { // @StateObject保证实例全局唯一,不会随视图刷新被销毁 @StateObject private var userData = UserData() var body: some Scene { WindowGroup { ContentView() // 注入实例到整个视图树 .environmentObject(userData) } } }
第三步:在任意视图读写共享数据
不管是启动时的信息收集页、设置修改页还是信息展示页,都可以直接调用该实例,修改后所有关联视图自动同步更新:
示例1:设置页修改数据
struct SettingsView: View { // 读取全局注入的实例,不需要手动传参 @EnvironmentObject var userData: UserData var body: some View { Form { TextField("输入性别", text: $userData.gender) TextField("输入体重", value: $userData.weight, format: .number) TextField("输入资质信息", text: $userData.qualification) } } }
示例2:首页展示数据
struct HomeView: View { @EnvironmentObject var userData: UserData var body: some View { VStack { Text("性别:\(userData.gender)") Text("体重:\(userData.weight)kg") Text("资质:\(userData.qualification)") } } }
注意事项
- 全程不要重复初始化
UserData实例,仅保留App入口初始化的唯一一个实例即可保证数据全局统一 - 如果你使用iOS17及以上版本,可以用更简洁的
@Observable宏替代ObservableObject,实现逻辑和上述步骤一致 - 如果仅少量页面需要共享数据,也可以在页面跳转时将
@ObservedObject修饰的实例作为参数传递,同样可以实现同步更新
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

