更新 SwiftUI 列表中的选定对象
Posted
技术标签:
【中文标题】更新 SwiftUI 列表中的选定对象【英文标题】:Updating the selected object in a SwiftUI List 【发布时间】:2020-08-13 12:33:42 【问题描述】:当使用 List 是 SwiftUI 时,我有代码来更新工作正常的选定对象。但是,在所选对象发生更改之前,对所选对象的更改不会反映在列表中。
这是我的 List 正在显示的类的简化版本。
class Item: ObservableObject
let id = UUID()
@Published var name: String
init(name: String)
self.name = name
extension Item: Hashable
static func == (lhs: Item, rhs: Item) -> Bool
lhs.id == rhs.id
func hash(into hasher: inout Hasher)
hasher.combine(id)
这是我观点的简化版本。
struct TestView: View
@State var items = [
Item(name: "Item 1"),
Item(name: "Item 2"),
Item(name: "Item 3"),
Item(name: "Item 4")
]
@State var selectedItem: Item?
var body: some View
VStack
List(items, id: \.self, selection: $selectedItem) item in
Text(item.name)
HStack
Button items.append(Item(name: "New Item"))
label: Text("Add Item")
Button selectedItem?.name += "a"
label: Text("Update Item")
.disabled(selectedItem == nil)
.padding()
我打算使用范围 0..<items.count
并更新数组中的对象,但是当项目数量发生变化时这会崩溃。
屏幕录制:
【问题讨论】:
而不是@State
用于您的项目数组,您可能希望使用@ObservedObject
,因为Item
是ObservableObject
,name
作为其@Published
属性。跨度>
@MStrapko 不幸的是,这不适用于数组本身不符合 ObservableObject (实际上它本身是一个结构而不是一个类)。
【参考方案1】:
由于您的项目具有引用类型 (class Item
),因此当您修改每个对象时,状态数组中的引用不会更改,因此不会刷新视图。
您的模型的可能解决方案是将列表行分离到独立视图中,该视图将观察相应的项目更改
使用 Xcode 11.4 / macOS 10.15.6 测试
struct ListRowView: View
@ObservedObject var item: Item
var body: some View
Text(item.name)
所以主列表变成了
List(items, id: \.self, selection: $selectedItem) item in
ListRowView(item: item)
【讨论】:
啊,天才!我什至从未考虑过我可以将@ObservedObject
用于数组内的对象。以上是关于更新 SwiftUI 列表中的选定对象的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI 中的 List 是不是复用类似于 UITableView 的单元格?