Swiftui WatchKit List с onDelete и подтверждением оповещения не обновляет представление таблицы правильно - PullRequest
2 голосов
/ 29 марта 2020

Может ли кто-нибудь указать мне правильное направление относительно того, как реализовать простой список с помощью функции подтверждения удаления, или, по крайней мере, показать здесь передовую практику.

Ниже код будет работать, если часть оповещения будет удалена и действие удаления немедленное. Каким-то образом, представление подтверждения-предупреждения приводит к тому, что удаление удаляется из неправильного списка лиц. Первое удаление также выдает консольное предупреждение:

[TableView] Только одно предупреждение: UITableView было приказано расположить видимые ячейки и другое содержимое, не находясь в иерархии представления (представление таблицы или одно из ее суперпредставлений). не был добавлен в окно). Это может привести к ошибкам, заставляя представления внутри табличного представления загружаться и выполнять компоновку без точной информации (например, границ табличного представления, сбора признаков, полей макета, вставок безопасной области и т. Д. c), а также приведет к ненужным потерям производительности из-за дополнительные макеты проходит. Создайте символьную c точку останова в UITableViewAlertForLayoutOutsideViewHierarchy, чтобы перехватить это в отладчике и посмотреть, что вызвало это, чтобы можно было вообще избежать этого действия, если это возможно, или отложить его, пока представление таблицы не будет добавлено в окно.

Однако я понятия не имею, как решить эту проблему, не удаляя предупреждение. Кстати, этот точный код работал пару недель за go до того, как мой ма c обновил xcode, я верю.

Duplicated

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()
    }
}

1 Ответ

2 голосов
/ 30 марта 2020

Проблема связана с конфликтом при обновлении закрытия оповещения и удалении записи списка. Обходной путь - отложить удаление, как показано ниже (протестировано с 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()
                }
            })
}
...