有人可以为我指出如何实施具有确认删除功能的简单列表的正确方向,或者至少在此处显示最佳做法。
如果删除了警报部分并且立即执行了删除操作,则下面的代码将起作用。 不知何故,确认警报的显示使删除作用在错误的人员名单上。第一次删除还会发出控制台警告:
[TableView]仅警告一次:通知UITableView布置其可见单元格和其他内容,而不必放在视图层次结构中(表视图或其父视图之一尚未添加到窗口)。这可能会由于迫使表视图中的视图在没有准确信息(例如表视图边界,特征收集,布局边距,安全区域插入等)的情况下加载和执行布局而导致错误,并且还会由于额外的布局传递而导致不必要的性能开销。在UITableViewAlertForLayoutOutsideViewHierarchy上创建一个符号断点,以在调试器中捕获此断点,并查看引起此情况的原因,因此,如果可能,您可以完全避免执行此操作,或者将其推迟到将表视图添加到窗口中。
但是,我不知道如何在不删除警报的情况下解决此问题。顺便说一下,这个确切的代码在我的Mac更新xcode之前的几个星期前就已经起作用了。
import Foundation
import SwiftUI
import Combine
struct Person: Identifiable{
var id: Int
var name: String
init(id: Int, name: String){
self.id = id
self.name = name
}
}
class People: ObservableObject{
@Published var people: [Person]
init(){
self.people = [
Person(id: 1, name:"One"),
Person(id: 2, name:"Two"),
Person(id: 3, name:"Three"),
Person(id: 4, name:"Four")]
}
}
struct ContentView: View {
@ObservedObject var mypeople: People = People()
@State private var showConfirm = false
@State private var idx = 0
func setDeletIndex(at idxs:IndexSet) {
self.showConfirm = true
self.idx = idxs.first!
}
func delete() {
self.mypeople.people.remove(at: idx)
}
var body: some View {
VStack {
List {
Text("Currently \(mypeople.people.count) persons").font(.footnote)
.alert(isPresented: $showConfirm) {
Alert(title: Text("Delete"), message: Text("Sure?"),
primaryButton: .cancel(),
secondaryButton: .destructive(Text("Delete")) {
self.delete()
})
}
ForEach(mypeople.people){ person in
Text("\(person.name)")
}.onDelete { self.setDeletIndex(at: $0) }
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
答案 0 :(得分:2)
该问题是由于更新警报关闭与删除列表记录冲突。解决方法是延迟删除,如下所示(已通过Xcode 11.4测试)
Text("Currently \(mypeople.people.count) persons").font(.footnote)
.alert(isPresented: $showConfirm) {
Alert(title: Text("Delete"), message: Text("Sure?"),
primaryButton: .cancel(),
secondaryButton: .destructive(Text("Delete")) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { // here !!
self.delete()
}
})
}