Travailler avec les Contrôleurs de Vue de table dans Swift

Écrit par Reinder de Vries le 3 août 2020 dans Développement d’applications, iOS

 Travailler avec des contrôleurs de vue de table dans Swift

Dans ce tutoriel, je vais vous montrer étape par étape comment fonctionnent les contrôleurs de vue de table et comment vous pouvez les utiliser. Nous allons entrer dans la gamme complète de UITableViewController, en plongeant dans la programmation orientée objet, la délégation et les mécanismes en coulisses des vues de table.

Un contrôleur de vue de table affiche des informations structurées et reproductibles dans une liste verticale. Vous utilisez la classe UITableViewController dans votre application iOS pour créer un contrôleur de vue de table.

Travailler avec un contrôleur de vue de table signifie également travailler avec quelques concepts de développement iOS importants, tels que le sous-classement, le modèle de conception de délégation et la réutilisation des vues.

C’est important pour les développeurs iOS professionnels et pratiques (vous!) pour maîtriser le travail avec les contrôleurs de vue de table. Une fois que vous vous êtes habitué à travailler sur un composant d’interface utilisateur aussi multiforme, comme UITableViewController, d’autres aspects plus complexes du développement iOS commenceront également à avoir du sens.

Prêt? Plongeons dedans !

  1. Fonctionnement d’un Contrôleur de Vue de Table
  2. Configuration d’un Contrôleur de Vue de Table Simple
  3. Codage De La Source de Données du Contrôleur de Vue de Table
  4. Fourniture de Cellules au Contrôleur de Vue de Table
  5. Réponse à l’Interaction de l’Utilisateur
  6. Lecture supplémentaire

Comment une Table Le contrôleur de vue fonctionne

Si vous avez déjà utilisé une application iOS, vous avez déjà utilisé des contrôleurs de vue de table. Ils sont utilisés fréquemment dans les applications iOS!

Voici un exemple de contrôleur de vue de table:

 Exemple de contrôleur de vue de table

Un contrôleur de vue de table a généralement ces composants visibles:

  • Une vue de tableau, qui est le composant de l’interface utilisateur, ou vue, qui s’affiche à l’écran. Une vue de table est une instance de la classe UITableView, qui est une sous-classe de UIScrollView.
  • Cellules de vue de tableau, qui sont les lignes ou les vues répétables affichées dans la vue de tableau. Une cellule de vue de table est une instance d’une classe UITableViewCell, et cette classe est souvent sous-classée pour créer des cellules de vue de table personnalisées.

Un contrôleur de vue de table repose également sur l’utilisation de ces composants, en coulisses:

  • Délégué de la vue de table, qui est responsable de la gestion de la disposition de la vue de table et de la réponse aux événements d’interaction de l’utilisateur. Un délégué de vue de table est une instance de la classe UITableViewDelegate.
  • Source de données de vue de table, qui est responsable de la gestion des données dans une vue de table, y compris les cellules et les sections de vue de table. Une source de données est une instance de la classe UITableViewDataSource.

Un contrôleur de navigation est souvent utilisé en conjonction avec un contrôleur de vue de table pour activer la navigation entre la vue de table et les contrôleurs de vue suivants, et pour afficher une barre de navigation au-dessus de la vue de table.

La partie la plus intéressante du travail avec les contrôleurs de vue de table est le contrôleur de vue de table lui-même! Comment ça ?

Connaissez-vous l’architecture Model-View-Controller ? Selon l’architecture Model-View-Controller, une vue de table et une cellule de vue de table sont des vues, et un contrôleur de vue de table est un contrôleur.Les vues

sont responsables de l’affichage visible des informations à l’utilisateur, avec une interface utilisateur (UI). Les contrôleurs sont responsables de la mise en œuvre de la logique, de la gestion des données et de la prise de décisions. Dit différemment: vous ne pouvez pas voir un contrôleur, mais il est là, gérant ce que vous voyez à travers les vues.

Lorsque vous utilisez un contrôleur de vue de table dans votre application, vous sous-classez la classe UITableViewController. La classe UITableViewController elle-même est une sous-classe de UIViewController.

Voici la hiérarchie des classes d’un exemple de contrôleur de vue de table qui affiche les informations de contact:

  • une instance de ContactsTableViewController
    • sous-classes UITableViewController
      • sous-classes UIViewController

Selon les principes de la programmation Orientée objet (POO), lorsque la classe RaceCar sous-classe la classe Vehicle, elle hérite des propriétés et fonctions de cette superclasse, telles que maxSpeed et drive().

La classe Vehicle est alors appelée la superclasse de RaceCar. Ce principe s’appelle l’héritage.

Source de confusion ? Ça peut l’être ! Pensez-y comme ça: pour que votre contrôleur de vue de table fonctionne CORRECTEMENT, vous devrez hériter d’un tas de code, vous n’avez donc pas à écrire tout ce code vous-même. La hiérarchie des classes et la POO sont là pour structurer cet héritage.

 Diagramme de classe de contrôleur de vue de table

Vous pouvez travailler avec des vues de table sans utiliser de contrôleur de vue de table. Ajoutez simplement un UITableView à un contrôleur de vue, fournissez-lui des implémentations des fonctions de délégué de vue de table et de source de données, et le tour est joué.

La classe UITableViewController fournit des implémentations par défaut de ces fonctions de source de données table view delegate et table view. C’est un aspect crucial du travail avec un contrôleur de vue de table!

Comme vous le verrez dans les prochains chapitres de ce tutoriel, nous remplacerons ces fonctions par nos propres implémentations. Nous pouvons personnaliser le contrôleur de vue de table en faisant cela.

Apprenez à créer des applications iOS

Commencez avec iOS 14 et Swift 5

Inscrivez-vous à mon cours de développement iOS et apprenez à créer d’excellentes applications iOS 14 avec Swift 5 et Xcode 12.

Configuration d’un Contrôleur de Vue de table Simple

D’accord, mettons tout cela en pratique. Dans cette section, nous allons créer un contrôleur de vue de table simple. Vous allez implémenter les fonctions nécessaires pour que cela fonctionne, et je vais vous expliquer comment elles fonctionnent au fur et à mesure. Passons à autre chose !

Vous pouvez utiliser 3 approches différentes pour travailler avec des interfaces utilisateur dans Xcode:

  1. Créer des vues par programme, c’est-à-dire les coder manuellement
  2. Configurer des interfaces utilisateur dans Interface Builder et les connecter avec du code Swift via XIBs
  3. Configurer des interfaces utilisateur et leurs transitions dans Interface Builder à l’aide de Storyboards
  4. (Techniquement, vous pouvez également utiliser SwiftUI, mais comme pour les contrôleurs de vue de table, cela dépasse le cadre de ce tutoriel.)

Il est fastidieux et improductif de coder les interfaces utilisateur à la main. Si vous ne faites pas attention aux Storyboards, ils finissent par cacher de la complexité au développeur. Nous allons travailler avec des Storyboards, tout en découvrant exactement comment ils fonctionnent en coulisses.

Voici ce que vous allez faire:

Tout d’abord, créez un nouveau projet Xcode via Fichier →Nouveau → Projet …. Assurez-vous de choisir le modèle d’application et choisissez Storyboard pour l’interface et UIKit App Delegate pour le cycle de vie.

Ensuite, procédez comme suit:

  1. Faites un clic droit sur votre projet dans le Navigateur de projet et choisissez Nouveau fichier
  2. Choisissez le modèle de classe Cocoa Touch (iOS)
  3. Choisissez UITableViewController pour la sous-classe de
  4. Nommez la classe ContactsTableViewController
  5. Ne cochez pas Également Créer un fichier XIB
  6. Enfin , cliquez sur Suivant et enregistrez le fichier à côté des autres fichiers Swift

Enfin, faites ceci:

  1. Allez dans Main.storyboard et supprimez la scène de Contrôleur de Vue existante
  2. Ajoutez un nouveau Contrôleur de Vue de Table au storyboard via la Bibliothèque
  3. Avec le contrôleur de vue de table sélectionné, allez dans l’Inspecteur des attributs et cochez la case Contrôleur de vue initial Is
  4. Enfin, allez dans l’Inspecteur d’identité et définissez la classe sur ContactsTableViewController

C’est tout! Vous avez maintenant un contrôleur de vue de table dans le storyboard du projet et vous l’avez connecté à la classe Swift ContactsTableViewController.

 Configuration du contrôleur de vue de table Xcode

Comme vous l’avez deviné, votre classe ContactsTableViewController est une sous-classe de UITableViewController. Vous pouvez le voir dans le fichier Swift, en haut, dans la déclaration de classe.

class ContactsTableViewController: UITableViewController { ···

Cette syntaxe signifie : la classe ContactsTableViewController est une sous-classe de UITableViewController.

Lorsque vous cliquez avec le bouton droit sur « UITableViewController » tout en maintenant la touche Option enfoncée, vous pouvez voir dans la déclaration de classe que UITableViewController est une sous-classe de UIViewController et est conforme aux protocoles UITableViewDelegate et UITableViewDataSource.

 Voir la documentation du Contrôleur de vue de table dans Xcode

C’est la puissance du contrôleur de vue de table! Il ne nous donne pas seulement les composants individuels pour créer une vue de table, le contrôleur fournit également une implémentation par défaut. C’est pourquoi nous sous-classons UITableViewController, au lieu de créer un contrôleur de vue vide avec une vue de table.

À ce stade, vous pouvez exécuter votre application avec Command-R ou le bouton de lecture, et voir le contrôleur de vue de table vide apparaître à l’écran.

Pourquoi est-ce, au fait? Nous n’avons encore rien codé ! En effet, le contrôleur de vue de table a une implémentation par défaut, qui affiche simplement les cellules vides à l’écran. Soigné!

 Exemple de contrôleur de vue de table dans le simulateur iPhone

Selon votre version de Xcode, nous avons utilisé le délégué de scène pour configurer le contrôleur de vue initial de votre projet d’application. En savoir plus ici : Le délégué de scène dans Xcode

Un XIB et une PLUME sont fondamentalement la même chose – ils contiennent des informations de mise en page. Un XIB a un format XML, tandis qu’un NIB a un format binaire. Le XML est compilé en binaire lorsque vous créez votre application, c’est pourquoi les fonctions d’UIKit parlent toujours d’une « plume », tandis que Xcode l’appelle toujours un « xib ».

Codage de la source de données du Contrôleur de vue de table

Maintenant que votre contrôleur de vue de table a été configuré, donnons-lui vie! Dans ce chapitre, nous nous concentrerons sur les différentes fonctions que vous devrez implémenter pour que votre contrôleur de vue de table fonctionne.

Comme expliqué précédemment, ces fonctions appartiennent soit au délégué du contrôleur de vue de table, soit à la source de données du contrôleur de vue de table. Ces deux protocoles utilisent la délégation pour personnaliser la vue de table.

Les fonctions les plus importantes pour UITableViewDataSource sont:

  • numberOfSections(in:)
  • tableView(_:numberOfRowsInSection:)
  • tableView(_:cellForRowAt:)

Les autres fonctions pertinentes pour UITableViewDelegate sont:

  • tableView(_:didSelectRowAt:)
  • tableView(_:willDisplay:for:)

Vous trouverez d’autres fonctions dans la documentation des développeurs Apple pour UITableViewDelegate et UITableViewDataSource.

Ajout des données de Contacts

Vous allez commencer par ajouter les données d’informations de contact pour le contrôleur de vue de table. Ajoutez la propriété suivante à la classe ContactsTableViewController:

let contacts:] = , , , , , , , , , , , , , , , , ]

C’est un rolodex qu’on aimerait tous avoir, non ? Voici comment cela fonctionne:

  • Le let contacts déclare une constante avec le nom contacts. Vous l’avez ajouté en tant que propriété à la classe, de sorte que chaque instance de classe a accès à cette constante dans tout le code de la classe.
  • Le type de contacts est ], qui est un tableau de tableaux de chaînes. Vous créez essentiellement un tableau, dont les éléments sont des tableaux de chaînes. (Un nom de variable et son type sont séparés par deux points :)
  • Le code = attribue un tableau littéral à contacts, rempli des noms et numéros de téléphone de quelques milliardaires.

Plus tard, nous pouvons utiliser le nombre d’éléments du tableau avec contacts.count. Et nous pouvons obtenir des noms et des numéros de téléphone individuels avec contacts et contacts, en utilisant la syntaxe des indices.

Enregistrement d’une classe de cellules de vue de table

Avant de pouvoir utiliser des cellules dans un contrôleur de vue de table, vous devez les enregistrer avec la vue de table. Vous pouvez le faire de deux manières:

  1. En fournissant une classe de cellule de vue de table et un identifiant
  2. En fournissant une cellule de vue de table XIB et un identifiant

Lorsque vous utilisez une cellule de vue de table personnalisée, vous souhaitez probablement enregistrer un XIB pour cela. Lorsque vous utilisez les cellules de vue de table par défaut ou une autre cellule programmatique, vous enregistrez la classe. On va utiliser la classe, pour l’instant !

Ajoutez le code suivant à la fonction viewDidLoad():

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

Assurez-vous de l’ajouter sous la ligne super.viewDidLoad(). Comme vous le savez probablement, la fonction viewDidLoad() fait partie du cycle de vie du contrôleur de vue et appartient à la classe UIViewController.

Vous remplacez la fonction viewDidLoad() pour répondre à cet événement dans le cycle de vie d’un contrôleur de vue, de sorte que vous pouvez configurer votre vue après son chargement. Dans notre cas, nous utilisons la fonction pour enregistrer la cellule de vue de table.

Lorsque vous enregistrez une cellule de vue de table, vous devez également fournir un identifiant. Il s’agit simplement d’associer la classe de la cellule à un nom que vous pourrez utiliser plus tard, lors de la mise en file d’attente de la cellule dans tableView(_:cellForRowAt:).

Êtes-vous toujours avec moi? Passons à autre chose !

Implémentant « numberOfSections(in:) »

La première fonction déléguée que nous allons implémenter est numberOfSections(in:).

Une vue de table peut avoir plusieurs sections ou groupes. Chaque groupe a un en-tête qui flotte au-dessus de la rangée verticale de cellules. Dans une application Contacts, vous pouvez regrouper les contacts par ordre alphabétique. Cela se fait en fait dans l’application Contacts sur iPhone, où les contacts sont regroupés de A à Z.

L’application que nous construisons ne comporte qu’une seule section. Ajoutez la fonction suivante à la classe:

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

Simple, non? La fonction renvoie 1 lorsqu’elle est appelée.

Implémentant « tableView(_:numberOfRowsInSection:) »

Une fonction similaire est tableView(_:numberOfRowsInSection:). Au lieu de fournir le nombre de sections, il fournit le nombre de lignes dans une section. Comme une vue de tableau affiche des cellules dans une liste verticale, chaque cellule correspond à une ligne dans la vue de tableau.

L’application que nous construisons n’a qu’une seule section, et cette section a un nombre d’éléments égal au nombre d’éléments du tableau contacts. Donc, c’est contacts.count!

Ajoutez la fonction suivante à la classe:

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

Tu vois comment ça marche ? Nous retournons simplement contacts.count. Si vous deviez ajouter un autre nom et un autre numéro de téléphone à contacts, cela apparaîtrait également bien dans la vue de table.

Comprendre les lignes et les sections

Notre application de contacts est unidimensionnelle, elle affiche juste une liste de noms et de numéros de téléphone, et elle n’utilise pas de groupes. Mais que se passe-t-il si vous avez une vue de table groupée?

Dans la plupart des cas, votre source de données, comme le tableau contacts, serait également multidimensionnelle. Vous organiseriez des groupes au premier niveau et des éléments individuels au deuxième niveau, « en dessous » des groupes.

- Countries - A - Afghanistan - Albania - ... - B - Bahamas - Bahrain - ... - C - Cambodia - Cameroon - ...

Le nombre de groupes est égal à countries.count et le nombre de pays dans un seul groupe est égal à countries.count, où x est l’indice de section. Cet index de section est fourni en tant que paramètre dans tableView(_:numberOfRowsInSection:).

Avez-vous remarqué que ces deux fonctions ont un paramètre appelé tableView? Cela fait partie du principe de programmation Orientée objet. Vous pouvez techniquement utiliser une source de données de vue de table et déléguer pour personnaliser plusieurs vues de table. Vous utiliseriez le tableView pour identifier la vue de table avec laquelle vous travaillez.

Imaginez que vous ayez une application de contacts qui peut afficher les numéros de téléphone par nom ou les numéros de téléphone organisés par entreprise. Vous pouvez l’implémenter de plusieurs manières, par exemple en réutilisant vos contrôleurs de vue de table. Ou si vous souhaitez réutiliser la mise en page de votre application Contacts pour afficher des informations similaires, comme des restaurants, des lieux ou des noms d’utilisateur Skype? C’est là que la réutilisation du code avec la POO entre en jeu !

Fournir des cellules au Contrôleur de Vue de table

Nous y arrivons! Passons à la fonction la plus importante d’un contrôleur de vue de table : tableView(_:cellForRowAt:).

Nous allons implémenter la fonction avant de plonger dans les détails, mais il y a quelques choses que vous devez comprendre à ce sujet:

  • Lorsqu’il est appelé
  • Qu’est-ce qu’un chemin d’index
  • Comment il réutilise les cellules

Tout d’abord, ajoutez la fonction suivante à la classe ContactsTableViewController:

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

Voici comment cela fonctionne:

  • La fonction remplace son implémentation de superclasse à partir de UITableViewController. Maintenant tu sais comment ça marche, non ? Nous remplaçons l’implémentation par défaut et remplaçons la nôtre. En effet, UITableViewController a déjà implémenté le délégué de la vue de table et la source de données pour nous.
  • Comme précédemment, la fonction a un paramètre tableView que nous pouvons utiliser pour identifier la vue de table sur laquelle cette fonction est appelée.
  • Un autre paramètre est indexPath, avec l’étiquette d’argument cellForRowAt. Le chemin d’index identifie les indices row et section de la cellule. Plus à ce sujet plus tard.
  • Le type de retour de fonction est UITableViewCell. C’est intéressant. Cette fonction est appelée par le contrôleur de vue de table, chaque fois que nous devons fournir une cellule de vue de table!

Lorsque vous faites défiler les contacts de cette application, chaque fois qu’une cellule doit être affichée à l’écran, la fonction tableView(_:cellForRowAt:) est appelée. A chaque fois ! Je te le prouverai dans un instant.

Ensuite, écrivons le corps de la fonction. Ajoutez le code suivant dans la fonction:

let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")cell.textLabel?.text = contactsreturn cell

Voici ce qui se passe:

  • Tout d’abord, nous retirons une cellule avec un identifiant. C’est exactement le même identifiant que nous utilisions auparavant, lors de l’enregistrement de la cellule. De cette façon, la vue de table sait quel type de cellule nous voulons. La cellule mise en file d’attente est affectée à la constante cell. Nous avons maintenant une cellule de vue de table avec laquelle travailler. Plus d’informations sur le déqueuing plus tard.
  • Ensuite, nous imprimons des informations sur la Console. C’est pour que nous puissions voir quand cette fonction est appelée, quand l’application s’exécute.
  • Ensuite, nous attribuons le nom du contact à l’étiquette de texte de cette cellule de vue de table. Le contacts contient la valeur du nom du contact, auquel nous arrivons en utilisant indexPath.row. Chaque instance de UITableViewCell a une propriété textLabel de UILabel, et chaque étiquette de ce type a une propriété text. Vous l’utilisez pour définir le texte sur l’étiquette.

Ne vous inquiétez pas, nous allons examiner chacune de ces choses plus en détail. Tout d’abord, voyez si vous pouvez exécuter votre application. Voyez-vous les noms des contacts? Voyez-vous la sortie de débogage dans la console? Essayez de faire défiler l’application!

 Lignes de contrôleur de vue de table

Quand « tableView(_:cellForRowAt:) » Est-il appelé?

Si vous avez exécuté l’application Contacts et joué avec le défilement de haut en bas, vous ne pouvez pas vous empêcher de remarquer que chaque fois que vous faites défiler, la sortie de débogage apparaît dans la Console.

Chaque fois qu’une cellule qui n’était pas à l’écran auparavant apparaît, la fonction tableView(_:cellForRowAt:) est appelée et une nouvelle ligne apparaît dans la Console.

Alors, quand tableView(_:cellForRowAt:) est-il appelé? Chaque fois qu’une cellule de vue de table doit être affichée à l’écran!

Le contrôleur de vue de table a déterminé qu’une cellule est nécessaire, il appelle donc tableView(_:cellForRowAt:). Notre implémentation de cette fonction supprime une cellule, la modifie et la renvoie au contrôleur de vue de table. Le contrôleur de vue de table et le framework UIKit le rendent ensuite graphiquement à l’écran.

Qu’est-ce qu’un chemin d’index ?

Chaque fois que le contrôleur de vue de table a besoin d’une cellule de tableView(_:cellForRowAt:), il fournit un chemin d’index comme argument pour la fonction. Dans le corps de la fonction, vous pouvez utiliser le paramètre indexPath pour savoir exactement de quelle cellule le contrôleur de vue de table a besoin.

Un chemin d’index est comme une adresse ou une coordonnée dans une grille. Un graphique typique a un axe X et un axe Y, vous pouvez donc exprimer une coordonnée dans ce graphique comme x, y comme 0, 1 et 42, 3. De même, une feuille de calcul comporte des lignes et des colonnes avec des indices.

Une vue de table utilise des sections et des lignes. Comme indiqué précédemment, vous pouvez utiliser des sections pour regrouper des cellules. Notre application n’a qu’une seule section, et elle a contacts.count lignes. Les lignes de la vue de table s’étendent de haut en bas.

Dit différemment: les sections et les lignes d’une vue de tableau sont ce que sont les colonnes et les lignes d’une feuille de calcul. Un chemin d’index définit un emplacement dans la vue de table, à l’aide d’une ligne et d’une section.

Les lignes et les sections sont représentées par des nombres, appelés indices. Ces indices commencent à zéro, de sorte que la première ligne et la première section auront le numéro d’index 0.

Lorsque vous regardez la capture d’écran précédente, cela a beaucoup plus de sens. La première cellule a un chemin d’index 0, 0, la deuxième cellule 0, 1, se poursuivant jusqu’à la dernière cellule visible avec un chemin d’index 0, 11.

Le mécanisme de réutilisation de la vue de table

Ce qui est le plus remarquable à propos de la vue de table est son mécanisme de réutilisation des cellules. C’est assez simple, en fait.

  • Chaque fois qu’un contrôleur de vue de table doit afficher une cellule à l’écran, la fonction tableView(_:cellForRowAt:) est appelée, comme nous l’avons déjà discuté.
  • Au lieu de créer une nouvelle cellule de vue de table chaque fois que cette fonction est appelée, elle sélectionne une cellule précédemment créée dans une file d’attente.
  • La cellule se réinitialise à un état vide, efface son apparence et la cellule est à nouveau personnalisée dans tableView(_:cellForRowAt:).
  • Chaque fois qu’une cellule défile hors écran, elle n’est pas détruite. Il est ajouté à la file d’attente, en attente d’être réutilisé.

C’est assez intelligent, non? Au lieu de créer et de supprimer des cellules, vous les réutilisez simplement. Mais why pourquoi ?

La réutilisation des cellules nécessite beaucoup moins de mémoire. Le contrôleur de vue de table écrirait constamment en mémoire lors de la création et de la suppression de cellules. La gestion de la mémoire serait également plus intensive. Lorsque les cellules sont réutilisées, la mémoire est utilisée plus efficacement et moins d’opérations de mémoire sont nécessaires.

En outre, l’itt consomme un peu moins de CPU pour réutiliser les cellules au lieu de les créer et de les supprimer, car il y a tout simplement moins d’opérations impliquées dans la réutilisation, par rapport à la création et à la suppression de cellules.

Lorsque vous faites défiler rapidement une vue de tableau, vous ne voyez pas de nouvelles cellules – vous voyez les mêmes cellules encore et encore, avec de nouvelles informations.

Le code impliqué dans la réutilisation des cellules est le suivant:

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

La fonction dequeueReusableCell(withIdentifier:) tente de supprimer la file d’attente d’une cellule. Lorsqu’aucune cellule n’est dans la file d’attente, cela créera une cellule pour nous. L’identifiant est utilisé pour garder chaque type de cellule dans sa propre file d’attente et pour s’assurer que la classe correcte est utilisée pour créer de nouvelles cellules.

Apprenez à créer des applications iOS

Commencez avec iOS 14 et Swift 5

Inscrivez-vous à mon cours de développement iOS et apprenez à créer d’excellentes applications iOS 14 avec Swift 5 et Xcode 12.

Répondre à l’interaction de l’utilisateur

Il manque une chose à notre contrôleur de vue de table: la possibilité d’appeler les personnes de notre liste de contacts! Mais avant de faire cela, assurez-vous que vous pouvez également voir le numéro de téléphone d’un contact dans le contrôleur de vue de table.

La classe UITableViewCell par défaut a 4 types différents, tels qu’exprimés dans l’énumération UITableViewCellStyle. Vous pouvez choisir entre:

  • .default – une vue simple avec une ligne de texte noir
  • .value1 – une vue simple avec une ligne de texte noir à gauche et une petite étiquette bleue à droite (utilisée dans l’application Paramètres)
  • .value2 – une vue simple avec une ligne de texte noir à droite et une petite étiquette bleue à gauche (utilisée dans l’application Contacts)
  • .subtitle – une vue simple avec une ligne de texte noir et une ligne de texte gris plus petite en dessous

La plupart des développeurs utilisent des cellules de vue de table personnalisées de nos jours, vous ne verrez donc pas souvent ces types de cellules. Mais ils sont là !

Nous devons ajuster légèrement le code en tableView(_:cellForRowAt:). Remplacez la première ligne de la fonction par le code suivant:

var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier")if cell == nil{ cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier")}

Si vous regardez de près, vous verrez que nous avons supprimé la partie for: indexPath de l’appel dequeueReusableCell(...). Au lieu de cela, cette fonction renvoie maintenant une option. Lorsqu’elle ne peut pas supprimer une cellule, la fonction renvoie nil.

Nous sautons ensuite dans nous-mêmes pour créer la cellule, si c’est nil. Vous le voyez dans la deuxième partie du code. Vous utilisez une instruction conditionnelle if pour vérifier si cell est égal à nil, et si c’est vrai, vous créez la cellule à l’aide de l’initialiseur UITableViewCell(style:reuseIdentifier:).

Cet initialiseur obtient deux arguments, le style de cellule .subtitle et l’identifiant que nous avons utilisé précédemment.

À ce stade, nous avons un problème, car cell est une option maintenant! Son type est UITableViewCell?, mais le type de retour de fonction exige que nous retournions une instance avec un type non facultatif UITableViewCell.

Heureusement, c’est l’un de ces cas où nous pouvons utiliser en toute sécurité le déballage forcé pour déballer la valeur facultative. En raison de la façon dont notre code est écrit, il est impossible que cell soit nil au-delà du conditionnel. Vous pouvez garantir que cell n’est pas nil après l’instruction if.

Assurez-vous de mettre à jour la fonction pour utiliser le déballage forcé pour cell. Ajoutez également la ligne de code suivante sous cell!.textLabel ... pour définir le sous-titre de la cellule afficher le numéro de téléphone du contact.

cell!.detailTextLabel?.text = contacts

La fonction entière ressemble maintenant à ceci:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") if cell == nil { cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier") } print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)") cell!.textLabel?.text = contacts cell!.detailTextLabel?.text = contacts return cell!}

Enfin, assurez-vous de supprimer la ligne suivante de viewDidLoad(). Cela empêchera la vue de table d’initialiser les cellules avec le mauvais type.

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

Très bien! Exécutez votre application avec la commande + R ou le bouton de lecture, et vérifiez si cela fonctionne. Voyez-vous des noms et des numéros de téléphone? Bien !

Ensuite, pour la pièce-de-résistance, ajoutons cette fonction d’interaction utilisateur. Maintenant que vous avez appris les subtilités du contrôleur de vue de table, je pense que vous savez déjà comment fonctionne cette fonction suivante.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ if let url = URL(string: "tel://" + contacts) { UIApplication.shared.open(url) }}

Encore une fois, nous remplaçons l’implémentation par défaut de la fonction tableView(_:didSelectRowAt:). Cette fonction est appelée lorsqu’un utilisateur tape sur la cellule d’une vue de table et qu’elle appartient au protocole UITableViewDelegate. Comme les autres fonctions, il fournit le chemin d’index de la cellule qui est exploitée.

Dans le corps de la fonction, nous créons simplement une URL tel:// à partir du numéro de téléphone. Nous demandons ensuite à l’application d’ouvrir cette URL, ce qui indique à iOS de lancer un appel vers ce numéro. Ce code n’est là qu’à titre indicatif. Notez que cela ne fonctionne pas sur le simulateur iPhone et que les chiffres de notre application sont faux. (Pourtant, vous utiliseriez ce code si vous créez une véritable application de contacts!)

Vous pouvez ajouter le code suivant à la fonction si vous souhaitez vérifier si cela fonctionne CORRECTEMENT.

print("\(#function) --- Calling: \(contacts)")

Cela affichera un message de débogage lorsque vous appuyez sur la cellule de la vue de table.

Pour en savoir plus

Et c’est tout ce qu’il y a à faire! Cela a été tout un voyage, mais maintenant vous savez comment fonctionne un contrôleur de vue de table.