• 10 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 05/04/2023

Supprimez une cellule

Notre liste est maintenant belle, en plus d'être fonctionnelle ! Mais il y a un petit truc qui me chagrine, et vous allez voir tout de suite de quoi je parle avec cette image.

L'interface avec notre liste… et un élément avec un nom illisible a été ajouté
Skhfhdazdokazpodkacop

Un petit malin m'a piqué mon téléphone, et s'est amusé à écrire n'importe quoi dans ma liste. Or pour l'instant, on ne peut pas supprimer les éléments de notre liste. On va changer cela dans ce chapitre.

Un deuxième delegate

Pour y arriver, nous allons revenir sur le delegate pattern. Vous vous souvenez que, dans la partie précédente, nous avons utilisé le delegate pattern avec le protocole  UITableViewDataSource  pour remplir notre TableView.

Il existe un autre protocole qui utilise le delegate pattern. Il se nomme  UITableViewDelegate  et fonctionne exactement comme  UITableViewDataSource  , mais son rôle est différent :

  • UITableViewDataSource  permet de fournir les données à la TableView.

  • UITableViewDelegate  permet de gérer certaines actions de la TableView, comme la sélection des cellules, la suppression de cellules, la réorganisation de la liste ou la configuration des différents headers, footers, et autres.

C'est donc avec  UITableViewDelegate  que l'on va pouvoir supprimer des cellules de notre liste !

Il ne nous reste plus qu'à implémenter ce delegate. Je vous redonne les 4 étapes de la création du delegate pattern :

  1. On crée une liste de questions que la vue peut poser.

  2. La vue nomme un objet son delegate, en l'occurrence notre contrôleur.

  3. Le contrôleur s'engage à répondre aux questions sur la liste.

  4. Le contrôleur répond effectivement aux questions.

On va utiliser le storyboard avec un control drag depuis la TableView vers le contrôleur, pour nommer le contrôleur delegate de la TableView.

Un drag and drop allant jusqu'à Outlets, puis on sélectionne delegate
Le drag c'est la vie

Ensuite, il faut que le contrôleur adopte le protocole. Nous allons faire cela comme d'habitude, avec une extension :

extension ListViewController: UITableViewDelegate {

}

Dans cette extension, nous allons pouvoir maintenant ajouter les méthodes de notre delegate.

Implémentation de la méthode

Voici à quoi ressemble la méthode qui permet de gérer l'édition et donc la suppression d'une cellule :

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)

Cette méthode prend en paramètre  editingStyle  qui est une énumération contenant les différents styles d'éditions (  none  ,  insert  ,  delete  ). Ici, c'est bien sûr  delete  qui va nous intéresser. Et en deuxième paramètre, vous avez l'index de la cellule qui subit l'édition.

Pour implémenter cette méthode, on va commencer par se placer dans le cas de l'édition qui nous intéresse : la suppression.

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

   if editingStyle == .delete {

   }

}

Maintenant, nous allons pouvoir gérer la suppression. Pour cela, il y a une règle que vous devez suivre, sans quoi votre code va planter :

On supprime d'abord les données correspondant à la cellule, puis on supprime la cellule.

Autrement dit, dans notre cas, il faut d'abord supprimer l'élément dans notre tableau  presents  , puis on supprimera la cellule.

Pour cela, nous allons rajouter la méthode  removePresent  dans notre classe  PresentService  :

class PresentService {

   // (...)

   func removePresent(at index: Int) {

      presents.remove(at: index)

   }

}

Maintenant, nous allons l'utiliser dans notre méthode d'édition de la TableView :

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

   if editingStyle == .delete {

      PresentService.shared.removePresent(at: indexPath.row)

   }

}

On utilise ici  indexPath.row  pour supprimer le bon élément du tableau. Et enfin, pour supprimer la cellule, on utilise la méthode  deleteRows  de  UITableView  :

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

 
   if editingStyle == .delete {


      PresentService.shared.removePresent(at: indexPath.row)


      tableView.deleteRows(at: [indexPath], with: .automatic)

   }

}

Cette méthode prend en paramètre un tableau des index des cellules à supprimer. C'est pourquoi on lui passe un tableau contenant un seul élément : l'index de la cellule à supprimer. Le deuxième argument est une énumération de type  UITableViewRowAnimation  qui permet de choisir parmi différents styles de suppression de la cellule.

Et voilà ! Ces quelques lignes de code suffisent à ajouter la fonctionnalité désirée. Si vous lancez le simulateur et que vous glissez une cellule vers la gauche, vous devez obtenir ceci :

Un bouton Delete est apparu à droite de notre élément illisible
En glissant la cellule jusqu'au bout à gauche ou en cliquant sur Delete, la cellule est supprimée de la liste.

En résumé

Pour ajouter la fonctionnalité de suppression à vos listes, il faut :

  • Utiliser le delegate pattern avec  UITableViewDelegate  .

  • Implémenter la méthode  tableViewCommitEditingStyleForRowAtIndexPath  .

Il est temps de faire un petit pas de côté pour réfléchir sur ce que vous avez acquis jusqu'ici !

Exemple de certificat de réussite
Exemple de certificat de réussite