我创建了一个简单的例子来说明我所面临的问题。我有两个视图,ListView和EditView。 ListView正在观察包含用户名列表的UsersViewModel(复数)。
使用NavigationLink,我想显示一个表单,在其中可以编辑用户名,这让我感到困惑。我已经创建了一个UserViewModel(单数形式),并具有EditView观察到的形式,但是当我尝试通过从ForEach循环中传递值的方式调用EditView时,由于我没有传递UserViewModel而收到类型不匹配错误。
也许我误解了可观察对象。我以为我可以在编辑表单上更改用户名,导航回列表视图,然后在列表中看到更改。
struct ListView: View {
// Observe the Users View Model
@ObservedObject var usersViewModel = UsersViewModel()
var body: some View {
NavigationView {
List() {
ForEach(usersViewModel.users) { user in
// FAILS with cannot converted "user" to expected type userViewModel
NavigationLink (destination: EditView(userViewModel: user)) {
Text("Hello \(user.name)")
}
}
}
.navigationBarTitle("User List", displayMode: .inline)
.onAppear(){
usersViewModel.loadUsers()
}
编辑视图
struct EditView: View {
@ObservedObject var userViewModel: UserViewModel
var body: some View {
TextField("User Name", text: $userViewModel.user)
答案 0 :(得分:0)
无法将“用户”转换为预期的类型userViewModel
您可能想在两个视图中使用相同的null
(假设UserViewModel
是一个结构)。
更改您的EditView以在初始化中使用user
参数:
usersViewModel
并在父视图中传递它:
struct EditView: View {
@ObservedObject var usersViewModel: UsersViewModel
否则,由于用户可能是结构,因此您将在子视图中修改用户的其他副本。
答案 1 :(得分:0)
我通过将usersViewModel传递给editView而不是pawello2222建议的userViewModel来解决了这个问题,但是显然您需要知道要编辑哪个元素。
所以我做到了;
let users = usersViewModel.users.enumerated().map({ $0 })
NavigationView {
List() {
ForEach(users, id: \.element.id ) { index, user in
NavigationLink (destination: EditView(userViewModel: usersViewModel, index: index)) {
这似乎是long绕的,一定要枚举viewModel才能为EditView提供要编辑哪个元素的索引是不正确的方法?
它可以工作,但是我想知道正确的方法