• 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

Créez une cellule customisée

Dans ce chapitre, nous allons modifier l'aspect de nos cellules pour qu'elles soient plus belles. L'objectif est le suivant :

D'un interface blanc sans icônes à un interface avec fond vert, des champs blancs et des icônes
D'une liste… à une belle liste !

Vous allez voir que ces cellules sont particulièrement flexibles ; c'est ce qui fait une bonne partie de la puissance des TableViews. Vous allez donc la plupart du temps travailler avec des cellules de votre création.

Design dans le storyboard

Nous allons commencer par revoir le design directement dans le storyboard.

Couleur de fond

Démarrons avec la couleur de fond de notre TableView. Choisissez la TableView, et modifiez la couleur de fond dans l'inspecteur d'attributs (comme d'habitude dans la section View).

Dans le menu déroulant sur le côté, sélectionnez une couleur dans Background
Dans l'inspecteur d'attribut, sélectionnez une couleur dans Background

Séparateurs

Notre nouveau design nous permet de nous passer des séparateurs proposés par défaut dans une TableView. Je vous suggère de supprimer ces séparateurs. Pour cela, sélectionnez la TableView et passez le paramètre Separator à None dans l'inspecteur d'attributs.

Dans la Table View, paramètre separator = None
Pas de séparateur

Taille de la cellule

Nous allons maintenant agrandir la taille de la cellule. Pour cela, sélectionnez la cellule et rendez-vous dans l'inspecteur de taille. Vous pouvez passer le paramètre Row Height à 90 :

Le Row Height est associé à la valeur 90
Row height = 90

Couleur de fond de la cellule

Comme vous pouvez le voir dans la hiérarchie des vues, la cellule a une Content View. C'est cette view qui, comme son nom l'indique, contient l'ensemble des vues qui seront affichées dans la cellule.

Dans le menu Table View apparaît un menu ToyCell dans lequel on sélectionne Content View
Content View

Cette vue est simplement de type  UIView  . Je vous invite à changer sa couleur pour qu'elle soit verte et se fonde avec la couleur de fond de la TableView. Cela va nous permettre de voir le fond vert de la TableView, et d'obtenir l'effet désiré.

Contenu de la cellule

Ça y est ! Nous allons nous attaquer au design de la cellule en elle-même. Pour cela, il faut d'abord changer le style de la vue à custom dans l'inspecteur d'attributs.

Dans la Table View Cell, le style Custom est sélectionné
Style : Custom

Regardons un peu le résultat que l'on souhaite obtenir :

La liste sur fond vert avec les logos asociés aux types de cadeaux Barbie (Matel), puis Paris-San Francisco (10 Days), puis Introduction à iOS (OpenClassrooms)
Notre whishlist

Il y a donc 4 vues :

  • Une vue blanche avec un effet ombré qui ne prend pas tout à fait tout le contenu de la cellule.

  • Une icône qui dépend de la catégorie de l'élément.

  • Un label de titre.

  • Un label de détail.

Je vous invite à rajouter tout cela dans la cellule, et à créer les contraintes nécessaires. Il n'y a rien de particulier ici.

Le Prototype Cells avec l'icône
Voici ce que cela donne pour moi

Création d'une sous-classe

Maintenant que notre cellule est toute belle, il va falloir l'utiliser ! Pour cela, il faut que l'on puisse modifier les labels et l'image que nous avons ajoutés manuellement dans la cellule.

Le problème, c'est que  UITableViewCell  ne connaît pas ces vues que nous avons ajoutées.

Alors, comment faire ? La solution est simple : nous allons créer une sous-classe de  UITableViewCell  , et lui ajouter nos vues sous forme de propriétés.

Création de la classe

Créez un nouveau fichier, cmd + n , et choisissez Cocoa Touch Class :

Dans iOS on sélectionne la source Cocoa Touch Class
Source : Cocoa Touch Class

Ensuite, choisissez de créer une sous-classe de  UITableViewCell  . Puis nommez-la  PresentTableViewCell  (car elle va servir à afficher des cadeaux) :

Class : PresentTableViewCell  Subclass of : UITableViewCell Language : Swift
Class : PresentTableViewCell

Et enregistrez le fichier dans votre dossier  View  . Vous devriez obtenir un fichier  PresentTableViewCell.swift  qui contient ceci :

import UIKit

class PresentTableViewCell: UITableViewCell {

   override func awakeFromNib() {

      super.awakeFromNib()

      // Initialization code

   }

   override func setSelected(_ selected: Bool, animated: Bool) {

      super.setSelected(selected, animated: animated)


      // Configure the view for the selected state

   }

}

Dans ce fichier, on vous propose de faire l'override de deux méthodes de  UITableViewCell  :

  • awakeFromNib  : cette méthode est utilisée lorsqu'une vue est initialisée depuis un storyboard. C'est ici que vous pouvez customiser votre cellule. Par exemple, dans notre cas, nous allons rajouter une ombre sur notre vue blanche.

  • setSelected  : cette méthode vous permettra de modifier l'aspect selon l'état de la vue : sélectionnée ou non. Nous n'en aurons pas besoin, donc vous pouvez supprimer cette méthode.

Connexion avec le storyboard

Maintenant, il nous faut modifier le type de notre cellule pour lui dire que désormais elle utilise le type  PresentTableViewCell  . Pour cela, sélectionnez la cellule dans le storyboard, allez dans l'inspecteur d'identité et modifiez sa classe :

Zoom sur la Custom Class  Class : PresentTableViewCell Module : Whismas  Inherit module From Target est coché
Class : PresentTableViewCell
Zoom sur Table View Cell : Style : Custom Identifier : PresentCell
ID : PresentCell
let cell = tableView.dequeueReusableCell(withIdentifier: "PresentCell", for: indexPath)

Nous allons maintenant connecter les différentes vues de notre cellule à notre nouvelle classe pour pouvoir les modifier comme nous le souhaitons. Pour cela, il suffit de créer des outlets entre les vues et notre classe. Vous savez faire, voici à quoi doit ressembler notre classe ensuite :

class PresentTableViewCell: UITableViewCell {

   @IBOutlet weak var iconView: UIImageView!

   @IBOutlet weak var titleLabel: UILabel!

   @IBOutlet weak var subtitleLabel: UILabel!

   @IBOutlet weak var whiteView: UIView!

   override func awakeFromNib() {

      super.awakeFromNib()

   }

}

Implémentation de la classe

Maintenant que notre classe est connectée, nous allons l'implémenter ! Je vous propose de commencer par rajouter notre petite ombre :

override func awakeFromNib() {

   super.awakeFromNib()

   addShadow()

}

private func addShadow() {

   whiteView.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.7).cgColor

   whiteView.layer.shadowRadius = 2.0

   whiteView.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)

   whiteView.layer.shadowOpacity = 2.0
 
}

Maintenant que ce petit détail de design est réglé, nous allons pouvoir configurer notre cellule. L'objectif ici est de créer une méthode que nous pourrons utiliser dans notre contrôleur pour configurer le contenu de notre cellule. Il faut configurer trois choses :

  • le texte de nos deux labels ;

  • l'icône que nous voulons afficher.

Pour cela, nous allons créer la méthode  configure  suivante :

func configure(withIcon icon: String, title: String, subtitle: String) {

   iconView.image = UIImage(named: icon)

   titleLabel.text = title

   subtitleLabel.text = subtitle

}

Et voilà, notre cellule customisée est prête ! Il ne nous reste plus qu'à l'utiliser dans le contrôleur.

Utilisation de PresentTableViewCell dans le contrôleur

Nous allons modifier notre méthode  cellForRow  qui pour l'instant ressemble à ceci :

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

   let cell = tableView.dequeueReusableCell(withIdentifier: "PresentCell", for: indexPath)

   let present = PresentService.shared.presents[indexPath.row]

   cell.textLabel?.text = present.description

   cell.detailTextLabel?.text = present.detail

   return cell
   
}

Pour commencer, nous allons vérifier que notre cellule est bien du type  PresentTableViewCell  :

guard let cell = tableView.dequeueReusableCell(withIdentifier: "PresentCell", for: indexPath) as? PresentTableViewCell else {

   return UITableViewCell()

}

Si ce n'est pas le cas, on renvoie une cellule standard.

Maintenant que l'on sait que l'on a affaire à une  PresentTableViewCell  , on va pouvoir utiliser notre méthode  configure  :

let present = PresentService.shared.presents[indexPath.row]

cell.configure(withIcon: "À FAIRE", title: present.description, subtitle: present.detail)

Vous noterez ici que je ne me suis pas encore occupé de l'icône. Le problème est que notre protocole  Present  n'a pas de propriété  icon  qui contiendrait le nom d'une image.

Nous allons régler cela tout de suite :

protocol Present {

   var description: String { get }

   var detail: String { get }

   var icon: String { get }

}

Il faut maintenant que nos trois types  Trip  ,  Book  et  Toy  se conforment à cette nouvelle exigence. Pour cela, vous pouvez remarquer, dans les assets du projet, que j'ai rajouté pour vous trois images nommées respectivement  TripIcon  ,  BookIcon  et  ToyIcon  .

C'est ce que nous allons utiliser :

extension Trip: Present {

   // (...)

   var icon: String { return "TripIcon" }
 
}

extension Book: Present {
 
   // (...)
 
   var icon: String { return "BookIcon" }
 
}

extension Toy: Present {
 
   // (...)

   var icon: String { return "ToyIcon" }

}

Et maintenant, nous pouvons finaliser notre méthode  configure  :

cell.configure(withIcon: present.icon, title: present.description, subtitle: present.detail)

Et voilà ! Nous avons maintenant une cellule toute belle ! Je vous invite à lancer votre application dans le simulateur et à admirer le résultat.

Le résultat de l'application dans le simulateur. Le fond est vert, et les listes sont accompagnées d'icônes
Tadaa !

En résumé

Pour créer une cellule customisée, vous devez :

  • Designer votre cellule dans le storyboard.

  • Créer une sous-classe de  UITableViewCell  .

  • Connecter cette sous-classe à votre cellule dans le storyboard.

  • Créer les outlets dont vous avez besoin.

  • Créer une méthode qui vous permet de configurer facilement votre cellule.

  • Utiliser votre nouvelle classe et sa méthode de configuration dans votre contrôleur.

Dans le prochain chapitre, nous allons apprendre à supprimer des éléments de votre liste.

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