我创建了一个我所面临问题的简单示例。我有两个视图,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)
无法转换"用户";到预期类型userViewModel
您可能希望在两个视图中使用相同的UserViewModel
(假设user
是一个结构(。
更改您的EditView以期望init:中有usersViewModel
参数
struct EditView: View {
@ObservedObject var usersViewModel: UsersViewModel
并在父视图中传递:
NavigationLink (destination: EditView(usersViewModel: usersViewModel))
否则,由于用户可能是一个结构体,您将在子视图中修改用户的不同副本。
我已经通过将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)) {
这似乎很冗长,必须枚举viewModel才能为EditView提供要编辑的元素的索引肯定不是正确的方法吗?
它有效,但我想知道的正确方式