更新 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,因为ItemObservableObjectname 作为其@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 的单元格?

SwiftUI 列表中的可编辑文本字段

SwiftUI:列表中的数据有时出现有时不出现

SwiftUI:Firebase ForEach 列表执行编辑功能无法编辑选定的行项目

如何在 SwiftUI 列表中设置选定的行背景颜色?

SwiftUI:在列表中的两个视图之间画一条线/如何确定视图的中心位置?