You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI:如何将视图数据传递至ViewModel再到第二个视图?

问题修复方案:通过ViewModel同步视图间数据

核心问题分析

你的代码存在两个关键问题,导致第二个视图无法读取第一个视图的输入内容:

  1. 第一个视图的输入未绑定到ViewModel的共享属性
  2. 第二个视图创建了全新的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:40:42