SwiftUI - 在 NavigationView 中删除一行并不能可靠地更新详细信息视图

时间:2021-03-19 12:10:13

标签: swiftui refresh navigationview detailview

我正在使用 NavigationView 来呈现带有目标视图的项目列表,以显示项目详细信息。我希望仅在选择列表项时显示详细视图。以下代码演示了该问题:

import SwiftUI

/*
    Model
*/
struct Item: Identifiable, Hashable {
    let id = UUID()
    let date: Date
    let name: String
}

/*
    List view
*/
struct ContentView: View {
    
    @State var itemArray: [Item] = [
        Item(date: Date(), name: "Item 1"),
        Item(date: Date(), name: "Item 2"),
        Item(date: Date(), name: "Item 3")
    ]
    
    @State var selectedItem: Item?
    
    var body: some View {
        
        VStack {
            NavigationView  {
                List {
                    ForEach(itemArray, id: \.self) { item in
                        NavigationLink(
                            destination: DetailView(item: item),
                            tag: item,
                            selection: $selectedItem
                        ) {
                            Text("\(item.name)").font(.headline)
                        }
                        .contextMenu {
                            Button("Delete", action: {
                                delete(item)
                                //selectedItem = nil
                                //DispatchQueue.main.asyncAfter(deadline: .now() + 1) { delete(item) }
                            })
                        }
                    }
                    .onDelete() { offsets in
                        itemArray.remove(atOffsets: offsets)
                        //selectedItem = nil
                        //DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { itemStore.delete(offsets: offsets) }
                    }
                }
                
                // Uncommenting this provides a placeholder for the detail view but prevents onDelete on macOS
                //Text("Select item...")
            }
            
            Text(selectedItem?.name ?? "No selection")
        }
    }
    
    private func delete(_ item: Item) {
        var index: Int? = nil
        for i in 0..<itemArray.count {
            if item == itemArray[i] { index = i }
        }
        if index != nil { itemArray.remove(at: index!) }
    }
}

/*
    Detail view
*/
struct DetailView: View {
    var item: Item
    
    var body: some View {
        Text(item.name)
    }
}

当删除列表中的项目时会出现问题,并且根据占位符是否存在有两种奇怪的行为模式:

没有占位符:(注释掉 Text("Select item...")):

操作:选择项目 1,然后将其删除(通过滑动或使用上下文菜单)
结果: 预期行为:详细视图为空。实际行为:项目 1 的详细视图仍然存在

使用占位符:

出现预期行为,但不是列表中的最后一项

尝试的解决方法:

  1. 在删除之前将选择显式设置为 nil - 失败
  2. 按照建议使用索引 here - 失败
  3. 在删除之前有延迟的解决方法 1 - 有效,但有问题

我已在 macOS BigSur 11.2.3 和 iPadOS 14.4.1(横向)上对此进行了测试,两个平台的问题都相同

我的问题是:

  1. 这是一个错误,还是我遗漏了什么?
  2. 有可靠的解决方法吗?
  3. 当占位符存在时,如何让滑动删除显示在 macOS 上?

0 个答案:

没有答案
相关问题