Partager via


Hello, iOS multiécran - Immersion

Avertissement

Le concepteur iOS a été déconseillé dans Visual Studio 2019 version 16.8 et Visual Studio 2019 pour Mac version 8.8, et supprimé dans Visual Studio 2019 version 16.9 et Visual Studio pour Mac version 8.9. La méthode recommandée pour créer des interfaces utilisateur iOS est directement sur un Mac exécutant le Générateur d’interface de Xcode. Pour plus d’informations, consultez Conception d’interfaces utilisateur avec Xcode.

Au cours de la procédure pas à pas de démarrage rapide, nous avons généré et exécuté notre première application Xamarin.iOS multi-écran. Il est maintenant temps d’approfondir les notions de navigation et d’architecture iOS.

Dans ce guide, nous présentons le modèle MVC (Model-View-Controller) et son rôle dans l’architecture et la navigation iOS. Ensuite, nous nous intéressons au contrôleur de navigation pour apprendre à l’utiliser afin d’offrir une expérience de navigation naturelle dans iOS.

Modèle MVC (Model-View-Controller)

Dans le tutoriel Hello, iOS, nous avons appris que les applications iOS ont une seule fenêtre et que les contrôleurs de vues sont responsables du chargement de leurs hiérarchies de vues de contenu dans cette fenêtre. Dans la deuxième procédure pas à pas Phoneword, nous avons ajouté un deuxième écran à notre application et passé certaines données (une liste de numéros de téléphone) entre les deux écrans, comme l’illustre le diagramme ci-dessous :

Ce diagramme illustre le passage de données entre deux écrans

Dans notre exemple, les données étaient collectées dans le premier écran, passées du premier contrôleur de vue au second, puis affichées par le second écran. Cette séparation des écrans, contrôleurs de vues et données suit le modèle MVC (modèle-vue-contrôleur). Dans les sections suivantes, nous présentons les avantages de ce modèle, ses composants et la manière dont nous l’utilisons dans notre application Phoneword.

Avantages du modèle MVC

Le modèle MVC (Model-View-Controller) est un modèle de conception, autrement dit une solution d’architecture réutilisable à un problème courant ou cas d’usage dans le code. Le modèle MVC est une architecture destinée aux applications dotées d’une interface graphique utilisateur (GUI). Il attribue aux objets dans l’application un des trois rôles suivants : modèle (Model) (données ou logique d’application), affichage (View) (interface utilisateur) et contrôleur (Controller) (code-behind). Le diagramme ci-dessous illustre les relations entre les trois éléments du modèle MVC et l’utilisateur :

Ce diagramme illustre les relations entre les trois éléments du modèle MVC et l’utilisateur

Le modèle MVC s’avère utile car il fournit une séparation logique entre les différents composants d’une application GUI et facilite la réutilisation de code et d’affichages. Intéressons-nous maintenant de plus près à chacun des trois rôles.

Remarque

Le modèle MVC est vaguement analogue à la structure des pages ASP.NET ou des applications WPF. Dans ces exemples, l’affichage (View) est le composant réellement chargé de décrire l’interface utilisateur ; il correspond à la page ASPX (HTML) dans ASP.NET ou au XAML dans une application WPF. Le contrôleur (Controller) est le composant chargé de gérer l’affichage (View), qui correspond au code-behind dans ASP.NET ou WPF.

Modèle

L’objet Model est généralement une représentation propre à l’application des données à afficher ou à entrer dans l’affichage (View). Il est souvent peu défini : par exemple, dans notre application Phoneword_iOS, la liste des numéros de téléphone (représentés sous la forme d’une liste de chaînes) est le modèle. Si nous voulions générer une application multiplateforme, nous pourrions choisir de partager le code PhonewordTranslator entre nos applications iOS et Android. Nous pourrions considérer ce code partagé comme le modèle également.

Le modèle MVC ne tient absolument pas compte de la persistance des données ni de l’accès de l’objet Model. En d’autres termes, le modèle MVC n’a que faire de ce à quoi ressemblent nos données ni de la manière dont elles sont stockées. Il s’intéresse uniquement à la manière dont elles sont représentées. Par exemple, nous pourrions choisir de stocker nos données dans une base de données SQL ou de les rendre persistantes dans un mécanisme de stockage cloud ou encore d’utiliser simplement List<string>. Pour MVC, seule la représentation des données est incluse dans le modèle.

Dans certains cas, la partie Model du modèle MVC peut être vide. Par exemple, nous pourrions choisir d’ajouter certaines pages statiques à notre application pour expliquer le fonctionnement du convertisseur de numéros de téléphone, les raisons de sa création et la manière de nous contacter pour signaler des bogues. Ces écrans d’application seraient quand même créés à l’aide d’affichages et de contrôleurs, mais ils n’auraient pas de données Model réelles.

Remarque

Dans certains documents, la partie Modèle du modèle MVC peut faire référence au backend de toute l’application, pas seulement aux données qui s’affichent dans l’interface utilisateur. Dans ce guide, nous utilisons une interprétation moderne de la partie Model, mais cette distinction n’est pas particulièrement importante.

Affichage

Un affichage (View) est un composant chargé du rendu de l’interface utilisateur. Dans presque toutes les plateformes qui utilisent le modèle MVC, l’interface utilisateur se compose d’une hiérarchie d’affichages. Un affichage dans le modèle MVC peut être perçu comme une hiérarchie d’affichage avec un affichage unique (appelé affichage racine) en haut de la hiérarchie et autant d’affichages enfants (appelés sous-affichages) en dessous. Dans iOS, la hiérarchie de vues de contenu d’un écran correspond au composant Vue du modèle MVC.

Contrôleur

L’objet Controller est le composant qui relie tous les éléments ensemble et qui est représenté dans iOS par UIViewController. Nous pouvons le considérer comme le code de stockage d’un écran ou d’un ensemble d’affichages. L’objet Controller (ou contrôleur) est chargé d’écouter les demandes émises par l’utilisateur et de retourner la hiérarchie d’affichage appropriée. Il écoute les demandes émises à partir de l’affichage (clics de bouton, entrée de texte, etc.) et effectue le traitement, la modification de l’affichage et le rechargement de l’affichage appropriés. Le contrôleur est également responsable de la création ou de la récupération de l’objet Model à partir du magasin de données existant dans l’application et du remplissage de l’affichage avec ses données.

Les contrôleurs peuvent également gérer d’autres contrôleurs. Par exemple, un contrôleur peut charger un autre contrôleur s’il a besoin d’afficher un autre écran ou il peut gérer une pile de contrôleurs pour surveiller leur ordre et les transitions entre eux. Dans la section suivante, nous allons voir un exemple de contrôleur qui gère d’autres contrôleurs au fur et à mesure que nous présenterons un type spécial de contrôleur de vue iOS appelé contrôleur de navigation.

Dans l’application Phoneword, nous avons utilisé un contrôleur de navigation pour mieux gérer la navigation entre plusieurs écrans. Le contrôleur de navigation est un UIViewController spécialisé représenté par la classe UINavigationController. Au lieu de gérer une seule hiérarchie de vues de contenu, le contrôleur de navigation gère d’autres contrôleurs de vues, ainsi que sa propre hiérarchie de vues de contenu spéciale sous la forme d’une barre d’outils de navigation qui inclut un titre, un bouton Précédent et d’autres fonctionnalités facultatives.

Le contrôleur de navigation est courant dans les applications iOS. Il permet de naviguer dans les applications iOS de base telles que l’application Settings, comme l’illustre la capture d’écran ci-dessous :

Le contrôleur de navigation permet de naviguer dans les applications iOS telles que l’application Settings illustrée ici

Le contrôleur de navigation remplit trois fonctions principales :

  • Il fournit des crochets pour la navigation vers l’avant : le contrôleur de navigation utilise une métaphore de navigation hiérarchique où les hiérarchies de vues de contenu sont envoyées (push) dans une pile de navigation. Vous pouvez considérer qu’une pile de navigation est comme une pile de cartes à jouer, dans laquelle seule la carte du dessus est visible, comme l’illustre le diagramme ci-dessous :

    Ce diagramme illustre la navigation sous forme de pile de cartes

  • Il fournit éventuellement un bouton Précédent : Quand nous envoyons un nouvel élément dans la pile de navigation, la barre de titre peut afficher automatiquement un bouton Précédent qui permet à l’utilisateur de revenir en arrière. En appuyant sur le bouton Précédent, le contrôleur de vue actif est retiré de la pile de navigation, et la précédente hiérarchie de vues de contenu se charge dans la fenêtre :

    Ce diagramme illustre un carte hors de la pile

  • Il fournit une barre de titre : la partie supérieure du contrôleur de navigation est appelée barre de titre. Elle est chargée d’afficher le titre du contrôleur de vue, comme l’illustre le diagramme ci-dessous :

    La barre de titre est chargée d’afficher le titre du contrôleur de vue

Contrôleur de vue racine

Un contrôleur de navigation ne gère pas une hiérarchie de vues de contenu, il n’a donc rien à afficher de lui-même. Un contrôleur de navigation est plutôt couplé à un contrôleur de vue racine :

Un contrôleur de navigation est couplé à un contrôleur de vue racine

Le contrôleur de vue racine représente le premier contrôleur de vue dans la pile du contrôleur de navigation. La hiérarchie de vues de contenu du contrôleur de vue racine est la première hiérarchie de vues de contenu à être chargée dans la fenêtre. Si nous souhaitons mettre toute notre application dans la pile du contrôleur de navigation, nous pouvons déplacer le Segue sans source dans le contrôleur de navigation, et définir le contrôleur de vue de notre premier écran en tant que contrôleur de vue racine, comme nous l’avons fait dans l’application Phoneword :

Le Segue sans source définit le contrôleur de vue des premiers écrans en tant que contrôleur de vue racine

Options de navigation supplémentaires

Le contrôleur de navigation est couramment utilisé pour prendre en charge la navigation dans iOS. Toutefois, il ne représente pas la seule option. Un contrôleur de barre d’onglets peut scinder une application en différentes zones opérationnelles. Un contrôleur de vue fractionné permet de créer des vues maître/détail. La combinaison des contrôleurs de navigation à ces autres paradigmes de navigation fournit de nombreuses manières flexibles de présenter du contenu iOS, et de naviguer dans celui-ci.

Gestion des transitions

Dans la procédure pas à pas Phoneword, nous avons traité la transition entre les deux contrôleurs de vues de deux manières différentes : d’abord avec un Segue de Storyboard, puis par programmation. Examinons ces deux options de plus près.

PrepareForSegue

Quand nous ajoutons un Segue avec une action Afficher au Storyboard, nous demandons à iOS d’envoyer (push) le deuxième contrôleur de vue dans la pile du contrôleur de navigation :

Définition du type de Segue à partir d’une liste déroulante

L’ajout d’un Segue au Storyboard suffit à créer une transition simple entre les écrans. Si nous souhaitons passer des données entre les contrôleurs de vues, nous devons remplacer la méthode PrepareForSegue et gérer les données nous-mêmes :

public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
    base.PrepareForSegue (segue, sender);
    ...
}

iOS appelle PrepareForSegue juste avant que la transition ne se produise et passe le Segue que nous avons créé dans le Storyboard à la méthode. À ce stade, nous devons définir manuellement le contrôleur de vue de destination du Segue. Le code suivant obtient un handle vers le contrôleur de vue de destination et le caste dans la classe appropriée, CallHistoryController, dans le cas présent :

CallHistoryController callHistoryController = segue.DestinationViewController as CallHistoryController;

Enfin, nous passons la liste de numéros de téléphone (la partie Model) depuis ViewController vers CallHistoryController en définissant la propriété PhoneHistory du CallHistoryController sur la liste des numéros de téléphone composés :

callHistoryController.PhoneNumbers = PhoneNumbers;

Le code complet permettant de passer des données à l’aide d’un Segue est le suivant :

public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
    base.PrepareForSegue (segue, sender);

    var callHistoryController = segue.DestinationViewController as CallHistoryController;

    if (callHistoryController != null) {
         callHistoryController.PhoneNumbers = PhoneNumbers;
    }
 }

Le processus de transition entre le premier contrôleur de vue et le deuxième dans le code est le même qu’avec un Segue, mais plusieurs étapes doivent être effectuées manuellement. Tout d’abord, nous utilisons this.NavigationController pour obtenir une référence au contrôleur de navigation dont la pile est celle où nous nous trouvons. Nous utilisons ensuite la méthode PushViewController du contrôleur de navigation pour envoyer manuellement le contrôleur de vue suivant dans la pile, en passant le contrôleur de vue et une option d’animation de la transition (nous affectons la valeur true).

Le code suivant gère la transition entre l’écran Phoneword et l’écran de l’historique des appels :

this.NavigationController.PushViewController (callHistory, true);

Pour pouvoir effectuer la transition vers le contrôleur de vue suivant, nous devons d’abord l’instancier manuellement à partir du Storyboard en appelant this.Storyboard.InstantiateViewController et en passant l’ID de Storyboard de CallHistoryController :

CallHistoryController callHistory =
this.Storyboard.InstantiateViewController
("CallHistoryController") as CallHistoryController;

Enfin, nous passons la liste de numéros de téléphone (la partie Model) depuis ViewController vers CallHistoryController en définissant la propriété PhoneHistory du CallHistoryController sur la liste des numéros de téléphone composés, tout comme nous l’avons fait quand nous avons géré la transition avec un Segue :

callHistory.PhoneNumbers = PhoneNumbers;

Le code complet pour la transition par programmation est le suivant :

CallHistoryButton.TouchUpInside += (object sender, EventArgs e) => {
    // Launches a new instance of CallHistoryController
    CallHistoryController callHistory = this.Storyboard.InstantiateViewController ("CallHistoryController") as CallHistoryController;
    if (callHistory != null) {
     callHistory.PhoneNumbers = PhoneNumbers;
     this.NavigationController.PushViewController (callHistory, true);
    }
};

Autres concepts introduits dans Phoneword

L’application Phoneword a introduit plusieurs concepts qui ne sont pas traités dans ce guide. Ces concepts sont les suivants :

  • Création automatique de contrôleurs de vues : quand nous entrons un nom de classe pour le contrôleur de vue dans le Panneau Propriétés, le concepteur iOS vérifie si cette classe existe, puis génère la classe de support du contrôleur de vue pour nous. Pour plus d’informations sur ce concept et d’autres fonctionnalités du concepteur iOS, reportez-vous au guide de présentation du concepteur iOS.
  • Contrôleur d’affichage de table : il CallHistoryController s’agit d’un contrôleur d’affichage table. Un contrôleur de vue de tableau contient une vue de tableau, l’outil de disposition et d’affichage de données le plus courant dans iOS. Les tables dépassent le cadre du présent guide. Pour plus d’informations sur les contrôleurs de vues de tableau, consultez le guide d’utilisation des tableaux et des cellules.
  • ID storyboard : la définition de l’ID storyboard crée une classe de contrôleur de vue dans Objective-C laquelle se trouve le code-behind du contrôleur de vue dans le Storyboard. Nous utilisons l’ID Storyboard pour rechercher la Objective-C classe et instancier le contrôleur de vue dans le Storyboard. Pour plus d’informations sur les ID de Storyboard, reportez-vous au guide de présentation des Storyboards.

Résumé

Félicitations ! Vous avez terminé votre première application iOS multi-écran.

Dans ce guide, nous avons présenté le modèle MVC et nous l’avons utilisé pour créer une application multi-écran. Nous avons également examiné les contrôleurs de navigation et leur rôle dans la navigation iOS. Vous avez maintenant acquis les bases solides dont vous avez besoin pour commencer à développer vos propres applications Xamarin.iOS.

Maintenant, apprenons à générer des applications multiplateforme avec Xamarin à l’aide des guides de présentation du développement mobile et de génération d’applications multiplateforme.