J'expérimente avec UITableView dans Swift 5.

Je souhaite insérer et supprimer des lignes.

Ma table plante lors de l'ajout de lignes supplémentaires. Le premier insert fonctionne bien.

class ViewController: UITableViewController {

    var items = [Int]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.backgroundColor = .white
        tableView.tableFooterView = UIView()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "CELL_ID")

        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.addMoreRows([1,2,3,4,5])
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.addMoreRows([6,7,8,9,10])
        }

    }

    private func addMoreRows(_ data: [Int]) {

        self.items.append(contentsOf: data)

        var indexPaths = [IndexPath]()

        for i in 0...items.count - 1 {
            indexPaths.append(IndexPath(row: i, section: 0))
        }

        tableView.insertRows(at: indexPaths, with: .left)
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CELL_ID", for: indexPath)
        cell.textLabel?.text = "Cell #\(indexPath.row)"
        return cell
    }
}

Arrêt de l'application en raison d'une exception non interceptée 'NSInternalInconsistencyException', raison: 'Mise à jour non valide: nombre de lignes non valide dans la section 0. Le nombre de lignes contenues dans une section existante après la mise à jour (10) doit être égal au nombre de lignes contenues dans cette section avant la mise à jour (5), plus ou moins le nombre de lignes insérées ou supprimées de cette section (10 insérées, 0 supprimées) et plus ou moins le nombre de lignes déplacées dans ou hors de cette section (0 déplacées vers l'intérieur, 0 déplacées en dehors).'

0
Harry Blue 19 juin 2019 à 22:35

3 réponses

Meilleure réponse

Votre boucle de création du tableau de chemins d'index est incorrecte. Vous voulez qu'il itère sur data.count, pas sur items.count. Et vous voulez que les nouveaux chemins d'index soient basés sur le précédent items.count.

private func addMoreRows(_ data: [Int]) {
    var indexPaths = [IndexPath]()

    for i in data.indices() {
        indexPaths.append(IndexPath(row: items.count + i, section: 0))
    }

    self.items.append(contentsOf: data)

    tableView.insertRows(at: indexPaths, with: .left)
}
2
rmaddy 19 juin 2019 à 19:41

Je pense que vous devez ajouter items après avoir calculé la collection IndexPath.

Vous devez également utiliser une plage pour prendre en charge la prochaine itération.

Essaye ça:

private func addMoreRows(_ data: [Int]) {

    var indexPaths = [IndexPath]()

    for i in items.count...items.count + data.count - 1 {
        indexPaths.append(IndexPath(row: i, section: 0))
    }

    self.items.append(contentsOf: data)

    tableView.insertRows(at: indexPaths, with: .left)
}
0
nodediggity 19 juin 2019 à 19:41

Dans addMoreRows, les chemins d'index commencent toujours par 0 donc dans le deuxième appel, 10 chemins d'index sont créés.

Un moyen plus fiable consiste à compter les éléments avant et après l'insertion

private func addMoreRows(_ data: [Int]) {
    let startIndex = self.items.count
    self.items.append(contentsOf: data)
    let endIndex = self.items.count

    var indexPaths = [IndexPath]()

    for i in startIndex..<endIndex {
        indexPaths.append(IndexPath(row: i, section: 0))
    }

    tableView.insertRows(at: indexPaths, with: .left)
}
0
vadian 19 juin 2019 à 19:41