49 votes

Suppression d'une rangée d'un UITableView en Swift 3 ?

Je suis nouveau dans le codage et l'apprentissage de Swift, je suis un tutoriel pour Swift 2 et je travaille avec Swift 3. Il y a quelques problèmes que je rencontre en suivant le tutoriel, celui-ci étant celui sur lequel je suis vraiment bloqué.

J'ai un tableau de noms et je suis en train de faire une fonction de balayage et de suppression pour eux qui les supprime d'une variable de noms qui est un tableau. J'ai sélectionné les fonctions qui ressemblent le plus au tutoriel dans xcode et je les ai remplies, mais mon application se plante aléatoirement lorsque je clique sur le bouton de suppression. Voici mon code pour le bouton de suppression...

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    let deleteAction = UITableViewRowAction(style: .destructive, title: "Delete") { (rowAction: UITableViewRowAction, indexPath: IndexPath) -> Void in

        print("Deleted")

        self.catNames.remove(at: indexPath.row)
        self.tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
        self.tableView.reloadData()
    }

2 votes

Il suffit de supprimer l'appel à reloadData .

1 votes

Pour votre information, chaque fois que vous posez une question sur une panne, vous devez inclure des détails pertinents sur la panne, y compris la ligne exacte qui a provoqué la panne et le message d'erreur complet.

0 votes

Retirer le reloadData L'appel ne résoudra pas le problème. Regardez les réponses ci-dessous.

133voto

ronatory Points 4328

Travaux pour Swift 3 y Swift 4

Utiliser la source de données UITableViewDataSource tableView(:commit:forRowAt:) voir aussi cette réponse aquí :

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
  if editingStyle == .delete {
    print("Deleted")

    self.catNames.remove(at: indexPath.row)
    self.tableView.deleteRows(at: [indexPath], with: .automatic)
  }
}

26 votes

Non, n'appelez pas reloadData juste pour supprimer une ligne. C'est une mauvaise pratique.

2 votes

Vous avez raison @rmaddy ! J'ai mis à jour la réponse et je voulais la lier à l'autre réponse qui la mentionnait avant, mais l'on l'a supprimée malheureusement.

3 votes

Il n'y a aucune raison d'utiliser begin/endUpdates autour d'une seule modification d'une vue de table.

29voto

ivan123 Points 186

Vous devez d'abord ajouter cette fonction

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

alors votre fonction est correcte mais il n'est pas nécessaire de recharger les données du tableau, il suffit d'appeler tableview.beingUpdates y tableview.endUpdates

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
       print("Deleted")
       self.catNames.remove(at: indexPath.row)
       self.tableView.beginUpdates()
       self.tableView.deleteRows(at: [indexPath], with: .automatic)
       self.tableView.endUpdates() 
    }
}

1 votes

C'est la valeur par défaut et l'ajouter ne résoudra pas le problème que rencontre le PO.

4 votes

Il n'y a aucune raison d'utiliser begin/endUpdates autour d'une seule modification d'une vue de table.

9voto

Jaydip Points 1069

Sur Swift 4 Essayez ceci

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    func tableView(_ tableView: UITableView, commit editingStyle:   UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == .delete) {
            arrStudentName.remove(at: indexPath.row)
            tableView.beginUpdates()
            tableView.deleteRows(at: [indexPath], with: .middle)
            tableView.endUpdates()
        }
    }

1 votes

Il est toujours bon de mentionner dans quel protocole ces méthodes s'inscrivent. Dans ce cas, il s'agit de UITableViewDataSource pour les deux méthodes.

3voto

suri Points 36
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {

        self.animals.remove(at: indexPath.row)

        self.dataDisplayTbleView.reloadData()
    }

}

0voto

user3182143 Points 1

Ma réponse pour vous

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

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
    if editingStyle == .delete
    {
        array.remove(at: indexPath.row)
        tblDltRow.reloadData()
    }
}

Vous devez rafraîchir la table

4 votes

Selon @rmaddy dans une autre réponse, le rechargement pour un simple élément supprimé est une mauvaise pratique. Au lieu de recharger, cela devrait être quelque chose comme self.tableView.deleteRows(at : [indexPath], with : .automatic). Vous ne savez vraiment pas comment la cellule fonctionne ou est définie. Imaginez une longue liste avec une cellule personnalisée complexe, peut-être avec des images, un rechargement pourrait forcer le téléchargement ou déclencher

0 votes

@le0diaz, En fait, aujourd'hui, j'ai le problème suivant : j'ai un tableau dans lequel nous montrons les listes d'utilisateurs et il y a un bouton de suppression dans chaque cellule. Si je supprime la première ligne, elle sera supprimée de la vue tableau mais si je supprime la 10ème ligne après avoir supprimé la première ligne. Le bouton de suppression aura un mauvais index et supprimera la ligne de la vue tableau.

0 votes

Bonjour, puis-je poser une question relative à moveRow ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X