2
votes

UITableView laisse le modèle de cellules vides après avoir supprimé une ou plusieurs lignes

TableView laissant des cellules vides

Répéter les cellules vides

Lors de la suppression de lignes à partir du bas

Après la suppression d'une ligne ou de plusieurs lignes dans mon TableView, les cellules TableView semblent se déplacer ou s'actualiser dans un façon étrange qui crée plusieurs lignes vides. Semble commencer par des lignes hors écran.

J'ai essayé d'utiliser beginUpdates, endUpdates et performBatchUpdates sans changement de comportement. J'ai également confirmé que le tableau de sources de données était correctement mis à jour, tout comme le nombre de lignes dans la vue de table.

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

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserPaymentCell

    let payment = paymentsArray[indexPath.row]
    cell.payment = payment

    cell.selectionStyle = .none

    cell.preservesSuperviewLayoutMargins = false
    cell.separatorInset = UIEdgeInsets(top: 0, left: 75, bottom: 0, right: 0)
    cell.layoutMargins = UIEdgeInsets.zero

    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 100
}


func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {

    let payment = paymentsArray[indexPath.row]

    if payment.payerUID == Auth.auth().currentUser?.uid {
        return true
    } else {
        return false
    }
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

    let payment = paymentsArray[indexPath.row]

    switch editingStyle {
    case .delete:
        deleteBillAndRefreshTotals(bill: payment, indexPath: indexPath)
    default:
        return
    }
}

func deleteBillAndRefreshTotals(bill: Bill, indexPath: IndexPath) {
    print("DELETING CELL")
    paymentsArray.remove(at: indexPath.row)
    paymentsTableView.deleteRows(at: [indexPath], with: .automatic)
    print(paymentsTableView.numberOfRows(inSection: 0))
}

Résultats attendus - pour la ligne à supprimer et toutes les cellules au-dessus ou en dessous de la cellule supprimée pour se déplacer ensemble.


4 commentaires

Pouvons-nous voir les méthodes de source de données s'il vous plaît?


@matt Inclus les méthodes de source de données pour vous!


Hmm, je ne vois rien de mal à cela, sauf que les deleteRows devraient être enveloppés dans un performBatchUpdates . Si cela ne résout pas le problème, pouvez-vous publier un petit projet de test qui démontre le problème? Fondamentalement, il ne devrait contenir que le code que vous avez déjà publié.


Au fait, voici mon exemple de projet téléchargeable et vous pouvez voir qu'il n'affiche pas ce problème. github.com/mattneub/Programming-iOS-Book-Examples/ tree / maste‌ r /…


3 Réponses :


0
votes
after perform delete operations call reloaddata method so after that tableview will refresh.
 func deleteBillAndRefreshTotals(bill: Bill, indexPath: IndexPath) {
    print("DELETING CELL")
    paymentsArray.remove(at: indexPath.row)
    paymentsTableView.reloaddata()
    print(paymentsTableView.numberOfRows(inSection: 0))
}

0 commentaires

0
votes

Vous pouvez essayer ce code:

paymentsTableView.beginUpdates()
paymentsTableView.deleteRows(at: [indexPath], with: .automatic)
paymentsTableView.endUpdates()


6 commentaires

Merci pour votre suggestion. J'ai essayé cela et il montre toujours le même comportement, ainsi que performBatchUpdates.


@chenders J'attends que vous fournissiez un exemple de projet reproductible.


@matt Je ne suis pas sûr de la meilleure façon d'en publier un petit échantillon. Avez-vous juste besoin du lien vers le projet complet sur GitHub?


@chenders Le but est pour vous de reproduire le problème dans un petit projet simple et de publier cela sur github. Vous voyez, je suppose que vous ne pourrez pas - parce que le problème est dû à un code totalement différent ailleurs dans votre projet réel que vous ne nous avez pas montré. Je vous défie de me montrer ce problème dans un projet minimal , pas dans votre projet complet. Je vous ai montré vous un projet de démonstration où ce problème ne se produit pas . Maintenant, vous me montrez un projet de démonstration où il fait.


@matt J'ai fait ce que vous avez suggéré et cela n'a pas reproduit le problème. J'ai donc examiné la possibilité que cela ait quelque chose à voir avec la cellule personnalisée elle-même. Effectivement, j'ai regardé le func prepareForReuse que j'avais ... commenté et cela a fonctionné comme il se doit. Je me suis vite rendu compte que je n'appelais pas super.prepareForReuse en premier dans la fonction, ce qui a transformé certaines de mes cellules en cellules blanches vides. Merci d'avoir suggéré de tout retirer!


@chenders Oui, c'est ma technique de débogage préférée!



4
votes
override func prepareForReuse() {
    super.prepareForReuse() // <--
    self.nameLabel.text = nil
    self.backgroundColor = .white
}
Within my custom cell implementation, the above function was being called without calling super.prepareForReuse first. Therefore causing the issues above.

0 commentaires