SwiftUI - 如何基于@ObservedObject 为每个列表视图项创建编辑视图
Posted
技术标签:
【中文标题】SwiftUI - 如何基于@ObservedObject 为每个列表视图项创建编辑视图【英文标题】:SwiftUI - How to create an edit view for each list view item based on @ObservedObject 【发布时间】:2020-09-18 09:09:01 【问题描述】:我创建了一个简单示例来说明我所面临的问题。我有两个视图,ListView 和 EditView。 ListView 正在观察包含用户名列表的 UsersViewModel(复数)。
使用 NavigationLink 我想展示一个可以编辑用户名的表单,这就是我感到困惑的地方。我创建了一个 UserViewModel(单数),我有 EditView 观察,但是当我尝试调用 EditView 传递 ForEach 循环中的值时,我得到一个类型不匹配错误,因为我没有传递 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)
【问题讨论】:
【参考方案1】:无法将“用户”转换为预期类型的 userViewModel
您可能希望在两个视图中使用相同的UserViewModel
(假设user
是一个结构)。
更改您的 EditView 以在 init 中使用 usersViewModel
参数:
struct EditView: View
@ObservedObject var usersViewModel: UsersViewModel
并在父视图中传递:
NavigationLink (destination: EditView(usersViewModel: usersViewModel))
否则,由于用户可能是一个结构,您将在子视图中修改用户的不同副本。
【讨论】:
【参考方案2】:我通过将 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 提供要编辑的元素的索引不是正确的方法吗?
它有效,但我想知道正确的方法
【讨论】:
以上是关于SwiftUI - 如何基于@ObservedObject 为每个列表视图项创建编辑视图的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中基于 SF Symbols 获得相同大小的圆形图像?
如何基于 min(X 或 Y)而不是 mid(X 或 y)SwiftUI 定位视图
如何从基于 SwiftUI 文档的应用程序中将多个文件保存在包文件夹中?