SwiftUI:如何将视图数据传递至ViewModel再到第二个视图?
问题修复方案:通过ViewModel同步视图间数据
核心问题分析
你的代码存在两个关键问题,导致第二个视图无法读取第一个视图的输入内容:
- 第一个视图的输入未绑定到ViewModel的共享属性
- 第二个视图创建了全新的ViewModel实例,而非使用共享的全局实例
修复步骤1:让第一个视图绑定到ViewModel的属性
ProfileFormView中原本使用本地@State变量存储日期,没有关联到ViewModel的@Published属性,用户选择的日期根本不会同步到ViewModel。修改代码如下:
struct ProfileFormView: View { @EnvironmentObject var appViewModel: AppViewModel var body: some View { NavigationView { Form { Section(header: Text("Personal Information")) { // 直接绑定到ViewModel的birthdate属性 DatePicker("Birthdate", selection: $appViewModel.birthdate, displayedComponents: .date) } } } } }
修复步骤2:让第二个视图使用共享的ViewModel实例
UserDataView中同时声明了@EnvironmentObject和@StateObject创建新实例,导致显示的是默认日期而非用户选择的内容。删除新实例的创建,直接使用全局共享的ViewModel:
struct UserDataView: View { @EnvironmentObject var viewModel: AppViewModel var body: some View { VStack { // 使用共享ViewModel的birthdate属性 Text("\(viewModel.birthdate)") Text("You are signed in") Button(action: { viewModel.signOut() }, label: { Text("Sign Out") .frame(width: 200, height: 50) .foregroundColor(Color.blue) }) } } }
额外保障:确保ViewModel全局注入
要保证所有视图拿到的是同一个ViewModel实例,需要在App入口处注入全局实例:
@main struct YourAppName: App { @StateObject var appViewModel = AppViewModel() var body: some Scene { WindowGroup { ContentView() .environmentObject(appViewModel) } } }
可选优化:完善年龄计算函数
原calcAge函数依赖字符串转换且存在强制解包风险,建议改为直接接收Date类型参数:
class AppViewModel: ObservableObject { @Published var birthdate = Date() func calcAge(birthdate: Date) -> Int { let calendar = Calendar(identifier: .gregorian) let ageComponents = calendar.dateComponents([.year], from: birthdate, to: Date()) return ageComponents.year ?? 0 } }
内容的提问来源于stack exchange,提问作者weekendwarrior
相关产品推荐
相关产品推荐

