Génération de code .xib dans Xamarin.iOS

L’outil Apple Interface Builder (« IB ») peut être utilisé pour concevoir visuellement des interfaces utilisateur. Les définitions d’interface créées par IB sont enregistrées dans des fichiers .xib . Les widgets et autres objets dans les fichiers .xib peuvent recevoir une « identité de classe », qui peut être un type personnalisé défini par l’utilisateur. L’utilisation de types personnalisés vous permet de personnaliser le comportement des widgets et d’écrire des widgets personnalisés.

Ces classes utilisateur sont normalement des sous-classes des classes de contrôleur d’interface utilisateur. Ils ont des sorties (propriétés) et des actions (événements) qui peuvent être connectées à des objets d’interface. Au moment de l’exécution, l’ib est chargé. À ce moment-là, les objets sont créés, et les sorties et les actions sont connectées dynamiquement aux différents objets d’interface utilisateur. Lorsque vous définissez ces classes managées, vous devez définir toutes les actions et sorties qui correspondent à celles attendues par IB. Visual Studio pour Mac utilise un modèle de type CodeBehind pour simplifier le code. Xcode a un modèle similaire Objective-C . Mais le modèle et les conventions de génération de code Xamarin.iOS ont été modifiés pour être plus familiers aux développeurs .NET.

Fichiers .xib et classes personnalisées

Il est possible de définir des types personnalisés dans des fichiers .xib , en plus d’utiliser les types existants de Cocoa Touch. Il est également possible d’utiliser des types définis dans d’autres fichiers .xib , ou définis uniquement en code C#. Actuellement, Interface Builder ne connaît pas les détails des types définis en dehors du fichier .xib actuel. Il ne les répertorie pas ou n’affiche pas leurs sorties et actions personnalisées. La suppression de cette limitation est prévue dans le futur.

Les classes personnalisées peuvent être définies dans un fichier .xib à l’aide de la commande « Ajouter une sous-classe » sous l’onglet « Classes » du Générateur d’interface. Nous faisons référence à ces classes en tant que classes « CodeBehind ». Si le fichier .xib a un fichier équivalent .xib.designer.cs dans le projet, Visual Studio pour Mac le remplira automatiquement avec des définitions de classes partielles pour toutes les classes personnalisées dans .xib. Nous faisons référence à ces classes partielles sous le nom de « classes de concepteur ».

Génération du code

La génération de code est activée par la présence d’un {0}fichier .xib.designer.cs , pour tout {0}fichier .xib avec une action de génération page. Visual Studio pour Mac génère des classes partielles dans le fichier de concepteur pour toutes les classes utilisateur qu’il peut trouver dans le fichier .xib. Visual Studio pour Mac génère des propriétés pour les sorties et des méthodes partielles pour les actions.

Le fichier du concepteur est automatiquement mis à jour lorsque le fichier .xib change et que Visual Studio pour Mac reprend le focus. Il n’est pas recommandé d’apporter des modifications au fichier de concepteur, car les modifications seront remplacées la prochaine fois Visual Studio pour Mac mettre à jour le fichier.

Inscription et espaces de noms

Visual Studio pour Mac génère les classes de concepteur à l’aide de l’espace de noms par défaut du projet pour l’emplacement du fichier du concepteur. Ce comportement est cohérent avec la génération d’espace de noms de projet .NET normale. L’espace de noms des fichiers de concepteur utilise les paramètres « espace de noms par défaut » du projet et ses stratégies de nommage « .NET ». Si l’espace de noms par défaut de votre projet change, les classes régénérées utilisent le nouvel espace de noms. Après la régénération, vous pouvez constater que vos classes partielles ne correspondent plus.

Pour rendre la classe détectable par le Objective-C runtime, Visual Studio pour Mac applique un [Register (name)] attribut à la classe . Bien que Xamarin.iOS inscrive automatiquement des classes dérivées, il utilise les noms .NET complets NSObject. L’attribut appliqué par Visual Studio pour Mac remplace le comportement Xamarin.iOS pour garantir que chaque classe est inscrite avec le nom utilisé dans le fichier .xib. Ajoutez l’attribut manuellement pour toutes les classes personnalisées définies à l’aide d’IB, sans utiliser Visual Studio pour Mac pour générer des fichiers de concepteur. Ainsi, vos classes managées correspondent aux noms de classes attendus Objective-C .

Les classes ne peuvent pas être définies dans plusieurs .xib, sinon elles sont en conflit.

Parties de classe non Designer

Designer classes partielles ne sont pas destinées à être utilisées en l’état. Les prises sont privées et aucune classe de base n’est spécifiée. Il est attendu que chaque classe ait une partie de classe « non concepteur » correspondante dans un autre fichier. Le fichier « non concepteur » définit la classe de base, manipule les sorties et définit les constructeurs requis pour instancier la classe à partir du code natif. Les modèles .xib par défaut ont les composants de classe « non concepteur », mais pour toutes les autres classes personnalisées que vous définissez dans un .xib, vous devez ajouter manuellement la partie non concepteur.

Cette séparation à l’aide de classes partielles est nécessaire pour la flexibilité. Par exemple, plusieurs classes CodeBehind peuvent sous-classer une classe abstraite managée commune, qui sous-classe la classe à sous-classer par IB.

Il est classique de placer des classes CodeBehind dans un {0}fichier .xib.cs à côté du fichier de {0}concepteur .xib.designer.cs .

Actions et sorties générées

Dans les classes de concepteur partiel, Visual Studio pour Mac génère des propriétés correspondant à toutes les prises connectées définies dans IB, et des méthodes partielles correspondant à toutes les actions connectées.

Propriétés de l’outlet

Designer classes contiennent des propriétés correspondant à tous les outlets définis sur la classe personnalisée. Ces propriétés activent la liaison différée. Il s’agit d’un détail d’implémentation du pont Xamarin.iOS vers Objective C. Considérez-les comme équivalents aux champs privés, destinés à être utilisés uniquement à partir de la classe CodeBehind. Rendez le champ public en ajoutant l’accesseur public au champ dans la partie classe non-concepteur.

Si les propriétés de sortie sont définies pour avoir un type (équivalent à NSObject), le générateur de id code du concepteur détermine actuellement le type le plus fort possible en fonction des objets connectés à cette prise, pour des raisons pratiques. Toutefois, ce comportement peut ne pas être pris en charge dans les versions ultérieures. Il est recommandé de taper explicitement fortement les sorties lors de la définition de la classe personnalisée.

Propriétés de l’action

Designer classes contiennent des méthodes partielles correspondant à toutes les actions définies sur la classe personnalisée. Ces méthodes n’ont pas d’implémentation. L’objectif des méthodes partielles est double :

  1. Si vous tapez partial dans le corps de la classe du composant de classe non-concepteur, Visual Studio pour Mac propose de saisie semi-automatique des signatures de toutes les méthodes partielles non implémentées.
  2. Les signatures de méthode partielle ont un attribut appliqué qui les expose au Objective-C monde, de sorte qu’elles peuvent être gérées en tant qu’action correspondante.

Vous pouvez ignorer la méthode partielle et implémenter l’action en appliquant l’attribut à une autre méthode. Ou laissez-le passer par une classe de base.

Si les actions sont définies pour avoir un type id d’expéditeur (équivalent à NSObject), le générateur de code du concepteur détermine actuellement le type le plus fort possible en fonction des objets connectés à cette action. Toutefois, ce comportement peut ne pas être pris en charge dans les versions ultérieures. Il est recommandé de taper explicitement les actions lors de la définition de la classe personnalisée.

Ces méthodes partielles sont créées uniquement pour C#, car CodeDOM ne prend pas en charge les méthodes partielles. Ils ne sont pas générés pour d’autres langues.

Utilisation de la classe Cross-XIB

Parfois, les utilisateurs souhaitent référencer la même classe à partir de plusieurs fichiers .xib , par exemple avec des contrôleurs d’onglets. Vous pouvez explicitement référencer la définition de classe à partir d’un autre fichier .xib ou définir à nouveau le même nom de classe dans le deuxième fichier .xib.

Ce dernier cas peut être problématique en raison de Visual Studio pour Mac traitement des fichiers .xib individuellement. Visual Studio pour Mac ne peut pas détecter et fusionner les définitions en double. Vous pouvez vous retrouver avec des conflits d’application de l’attribut Register plusieurs fois lorsque la même classe partielle est définie dans plusieurs fichiers de concepteur. Les versions récentes de Visual Studio pour Mac tentent de résoudre les conflits, mais elles peuvent ne pas toujours fonctionner comme prévu. À l’avenir, ce comportement ne sera probablement pas pris en charge et, au lieu de cela, Visual Studio pour Mac rendra tous les types définis dans tous les fichiers .xib et le code managé dans le projet directement visibles à partir de tous les fichiers .xib.

Résolution de type

Les types utilisés dans IB sont Objective-C des noms de type mappés à des types CLR à l’aide d’attributs Register. Lors de la génération de code, Visual Studio pour Mac résout les types CLR, en qualifiant entièrement les noms de type pour les Objective-C types. Ces Objective-C types sont encapsulés par le noyau Xamarin.iOS.

Actuellement, le générateur de code ne peut pas résoudre les types CLR à partir de noms de Objective-C type dans le code utilisateur ou les bibliothèques. Dans ce cas, il génère le nom de type textuellement. Il doit avoir le même nom que le Objective-C type pour résoudre correctement le type CLR. Le type CLR doit se trouver dans le même espace de noms que le code qui l’utilise. Les versions futures du générateur de code prendront en compte tous les Objective-C types du projet.