Storyboards unifiés dans Xamarin.iOS
iOS 8 inclut un nouveau mécanisme simple à utiliser pour créer l’interface utilisateur , le storyboard unifié. Avec un seul storyboard pour couvrir toutes les différentes tailles d’écran matérielles, des vues rapides et réactives peuvent être créées dans un style « design-once, use-many ».
Comme le développeur n’a plus besoin de créer un storyboard distinct et spécifique pour les appareils i Téléphone et iPad, ils ont la possibilité de concevoir des applications avec une interface commune, puis de personnaliser cette interface pour différentes classes de taille. De cette façon, une application peut être adaptée aux forces de chaque facteur de forme et chaque interface utilisateur peut être paramétrée pour offrir la meilleure expérience.
Classes de taille
Avant iOS 8, le développeur a utilisé UIInterfaceOrientation
et UIInterfaceIdiom
fait la distinction entre les modes portrait et paysage, et entre les appareils i Téléphone et iPad. Dans iOS8, l’orientation et l’appareil sont déterminés à l’aide de classes de taille.
Les appareils sont définis par les classes de taille, dans les axes verticaux et horizontaux, et il existe deux types de classes de taille dans iOS 8 :
- Normal : il s’agit d’une grande taille d’écran (par exemple, un iPad) ou d’un gadget qui donne l’impression d’une grande taille (par exemple, un iPad)
UIScrollView
- Compact : il s’agit d’appareils plus petits (tels qu’un i Téléphone). Cette taille prend en compte l’orientation de l’appareil.
Si les deux concepts sont utilisés ensemble, le résultat est une grille de 2 x 2 qui définit les différentes tailles possibles qui peuvent être utilisées dans les deux orientations différentes, comme illustré dans le diagramme suivant :
Le développeur peut créer un contrôleur de vue qui utilise l’une des quatre possibilités qui entraîneraient des dispositions différentes (comme indiqué dans les graphiques ci-dessus).
Classes de taille iPad
L’iPad, en raison de la taille, a une taille de classe régulière pour les deux orientations.
i Téléphone Classes de taille
I Téléphone a différentes classes de taille en fonction de l’orientation de l’appareil :
- Lorsque l’appareil est en mode portrait, l’écran a une classe compacte horizontalement et normalement verticalement
- Lorsque l’appareil est en mode paysage, les classes d’écran sont inversées du mode Portrait.
i Téléphone 6 classes de taille plus
Les tailles sont les mêmes que les i Téléphone antérieures lors de l’orientation portrait, mais différentes dans le paysage :
Étant donné que i Téléphone 6 Plus a un écran suffisamment grand, il est en mesure d’avoir une classe de taille de largeur régulière en mode Paysage.
Prise en charge d’une nouvelle échelle d’écran
I Téléphone 6 Plus utilise un nouvel écran Rétine HD avec un facteur d’échelle d’écran de 3,0 (trois fois la résolution d’écran i Téléphone d’origine). Pour offrir la meilleure expérience possible sur ces appareils, incluez de nouvelles illustrations conçues pour cette échelle d’écran. Dans Xcode 6 et versions ultérieures, les catalogues de ressources peuvent inclure des images de taille 1x, 2x et 3x ; ajoutez simplement les nouvelles ressources d’image et iOS choisissez les ressources appropriées lors de l’exécution sur un i Téléphone 6 Plus.
Le comportement de chargement d’image dans iOS reconnaît également un @3x
suffixe sur les fichiers image. Par exemple, si le développeur inclut une ressource d’image (à différentes résolutions) dans l’offre groupée de l’application avec les noms de fichiers suivants : MonkeyIcon.png
, MonkeyIcon@2x.png
et MonkeyIcon@3x.png
. Sur i Téléphone 6 Plus l’image MonkeyIcon@3x.png
sera utilisée automatiquement si le développeur charge une image à l’aide du code suivant :
UIImage icon = UIImage.FromFile("MonkeyImage.png");
Écrans de lancement dynamique
Le fichier d’écran de lancement s’affiche sous la forme d’un écran de démarrage pendant qu’une application iOS lance pour fournir des commentaires à l’utilisateur que l’application démarre réellement. Avant iOS 8, le développeur doit inclure plusieurs Default.png
ressources d’image pour chaque type d’appareil, orientation et résolution d’écran sur laquelle l’application s’exécuterait.
Nouveautés d’iOS 8, le développeur peut créer un fichier atomique .xib
unique dans Xcode qui utilise la disposition automatique et les classes de taille pour créer un écran de lancement dynamique qui fonctionnera pour chaque appareil, résolution et orientation. Cela réduit non seulement la quantité de travail requise par le développeur pour créer et gérer toutes les ressources d’image requises, mais elle réduit la taille de l’offre groupée installée de l’application.
Caractéristiques
Les caractéristiques sont des propriétés qui peuvent être utilisées pour déterminer comment une disposition change à mesure que son environnement change. Ils se composent d’un ensemble de propriétés (le HorizontalSizeClass
et basé surUIUserInterfaceSizeClass
), ainsi que de l’idiome d’interface (UIUserInterfaceIdiom
) et de l’échelle VerticalSizeClass
d’affichage.
Tous les états ci-dessus sont encapsulés dans un conteneur auquel Apple fait référence en tant que collection trait (), UITraitCollection
qui contient non seulement les propriétés, mais aussi leurs valeurs.
Environnement de caractéristiques
Les environnements trait sont une nouvelle interface dans iOS 8 et peuvent retourner une collection trait pour les objets suivants :
- Écrans (
UIScreens
). - Windows (
UIWindows
). - Afficher les contrôleurs (
UIViewController
). - Vues (
UIView
). - Presentation Controller ( ).
UIPresentationController
Le développeur utilise la collection Trait retournée par un environnement trait pour déterminer comment une interface utilisateur doit être disposée.
Tous les environnements de caractéristiques font une hiérarchie comme indiqué dans le diagramme suivant :
La collection Trait que chacun des environnements trait ci-dessus a été acheminé, par défaut, du parent à l’environnement enfant.
Outre l’obtention de la collection trait actuelle, l’environnement trait a une TraitCollectionDidChange
méthode, qui peut être substituée dans les sous-classes View ou View Controller. Le développeur peut utiliser cette méthode pour modifier l’un des éléments d’interface utilisateur qui dépendent des caractéristiques lorsque ces caractéristiques ont changé.
Collections de caractéristiques classiques
Cette section traite des types classiques de collections de caractéristiques que l’utilisateur rencontrera lors de l’utilisation d’iOS 8.
Voici une collection Trait classique que le développeur peut voir sur un i Téléphone :
Propriété | Valeur |
---|---|
HorizontalSizeClass |
Compact |
VerticalSizeClass |
Regular |
UserInterfaceIdom |
votre numéro de |
DisplayScale |
2.0 |
L’ensemble ci-dessus représente une collection de caractéristiques complètes, car elle a des valeurs pour toutes ses propriétés de caractéristiques.
Il est également possible d’avoir une collection Trait qui manque certaines de ses valeurs (dont Apple fait référence à Unspecified) :
Propriété | Valeur |
---|---|
HorizontalSizeClass |
Compact |
VerticalSizeClass |
Non spécifié |
UserInterfaceIdom |
Non spécifié |
DisplayScale |
Non spécifié |
En règle générale, toutefois, lorsque le développeur demande à Trait Environment pour sa collection Trait, il retourne une collection complète, comme indiqué dans l’exemple ci-dessus.
Si un environnement de caractéristiques (comme un affichage ou un contrôleur de vue) n’est pas à l’intérieur de la hiérarchie d’affichage actuelle, le développeur peut récupérer des valeurs non spécifiées pour une ou plusieurs des propriétés de caractéristiques.
Le développeur obtiendra également une collection Trait partiellement qualifiée s’il utilise l’une des méthodes de création fournies par Apple, telles que UITraitCollection.FromHorizontalSizeClass
, pour créer une collection.
Une opération qui peut être effectuée sur plusieurs collections traits consiste à les comparer les unes aux autres, ce qui implique de demander à une collection Trait s’il contient un autre. C’est que, pour toute caractéristique spécifiée dans la deuxième collection, la valeur doit correspondre exactement à la valeur de la première collection.
Pour tester deux caractéristiques, utilisez la Contains
méthode de UITraitCollection
passage de la valeur de la caractéristique à tester.
Le développeur peut effectuer les comparaisons manuellement dans le code pour déterminer comment mettre en page les vues ou les contrôleurs de vue. Toutefois, UIKit
utilise cette méthode en interne pour fournir certaines de ses fonctionnalités, comme dans le proxy d’apparence, par exemple.
Proxy d’apparence
Le proxy d’apparence a été introduit dans les versions antérieures d’iOS pour permettre aux développeurs de personnaliser les propriétés de leurs vues. Il a été étendu dans iOS 8 pour prendre en charge trait Collections.
Les proxys d’apparence incluent désormais une nouvelle méthode, AppearanceForTraitCollection
qui retourne un nouveau proxy d’apparence pour la collection trait donnée qui a été passée. Toutes les personnalisations effectuées par le développeur sur ce proxy d’apparence prennent uniquement effet sur les vues conformes à la collection trait spécifiée.
En règle générale, le développeur transmet une collection trait partiellement spécifiée à la AppearanceForTraitCollection
méthode, telle qu’une classe de taille horizontale de Compact, afin qu’elle puisse personnaliser n’importe quelle vue dans l’application compactée horizontalement.
Uiimage
Une autre classe à laquelle Apple a ajouté Trait Collection est UIImage
. Dans le passé, le développeur devait spécifier une @1X et @2x version d’une ressource graphique bitmap qu’il allait inclure dans l’application (par exemple, une icône).
iOS 8 a été développé pour permettre au développeur d’inclure plusieurs versions d’une image dans un catalogue d’images basé sur une collection trait. Par exemple, le développeur peut inclure une image plus petite pour l’utilisation d’une classe Trait Compact et d’une image de taille complète pour toute autre collection.
Lorsque l’une des images est utilisée à l’intérieur d’une UIImageView
classe, l’affichage Image affiche automatiquement la version correcte de l’image pour sa collection Trait. Si l’environnement trait change (par exemple, l’utilisateur bascule l’appareil du portrait vers le paysage), l’affichage image sélectionne automatiquement la nouvelle taille d’image pour qu’elle corresponde à la nouvelle collection trait et modifie sa taille pour qu’elle corresponde à celle de la version actuelle de l’image affichée.
UIImageAsset
Apple a ajouté une nouvelle classe à iOS 8 appelé UIImageAsset
pour donner au développeur encore plus de contrôle sur la sélection d’images.
Une ressource image inclut toutes les différentes versions d’une image et permet au développeur de demander une image spécifique qui correspond à une collection trait qui a été passée. Les images peuvent être ajoutées ou supprimées d’une ressource image, à la volée.
Pour plus d’informations sur les ressources d’image, consultez la documentation UIImageAsset d’Apple.
Combinaison de collections de caractéristiques
Une autre fonction qu’un développeur peut effectuer sur Trait Collections consiste à ajouter deux ensembles qui entraînent la collection combinée, où les valeurs non spécifiées d’une collection sont remplacées par les valeurs spécifiées dans une seconde. Cette opération est effectuée à l’aide de la FromTraitsFromCollections
méthode de la UITraitCollection
classe.
Comme indiqué ci-dessus, si l’un des traits n’est pas spécifié dans l’une des collections de caractéristiques et est spécifié dans un autre, la valeur est définie sur la version spécifiée. Toutefois, s’il existe plusieurs versions d’une valeur donnée spécifiées, la valeur de la dernière collection trait sera la valeur utilisée.
Contrôleurs d’affichage adaptatif
Cette section décrit les détails de la façon dont les contrôleurs d’affichage et de vue iOS ont adopté les concepts des caractéristiques et des classes de taille pour être automatiquement plus adaptatifs dans les applications du développeur.
Contrôleur d’affichage fractionné
L’une des classes view Controller qui a changé le plus dans iOS 8 est la UISplitViewController
classe. Dans le passé, le développeur utilise souvent un contrôleur de vue fractionné sur la version iPad de l’application, puis il devra fournir une version complètement différente de sa hiérarchie d’affichage pour la version i Téléphone de l’application.
Dans iOS 8, la UISplitViewController
classe est disponible sur les deux plateformes (iPad et i Téléphone), ce qui permet au développeur de créer une hiérarchie de contrôleurs de vue qui fonctionnera pour i Téléphone et iPad.
Lorsqu’un i Téléphone est dans le paysage, le contrôleur de vue fractionné présente ses vues côte à côte, comme il le ferait lors de l’affichage sur un iPad.
Substitution des caractéristiques
Les environnements de caractéristiques sont en cascade à partir du conteneur parent jusqu’aux conteneurs enfants, comme dans le graphique suivant montrant un contrôleur de vue fractionné sur un iPad dans l’orientation paysage :
Étant donné que l’iPad a une classe de taille régulière dans les orientations horizontales et verticales, la vue fractionnée affiche à la fois les vues maître et détail.
Sur un i Téléphone, où la classe taille est compacte dans les deux orientations, le contrôleur de vue fractionné affiche uniquement l’affichage des détails, comme indiqué ci-dessous :
Dans une application où le développeur souhaite afficher à la fois l’affichage maître et détaillé sur un i Téléphone dans l’orientation paysage, le développeur doit insérer un conteneur parent pour le contrôleur de vue fractionné et remplacer la collection trait. Comme indiqué dans le graphique ci-dessous :
A UIView
est défini comme parent du contrôleur de vue fractionné et la SetOverrideTraitCollection
méthode est appelée sur la vue en passant une nouvelle collection trait et ciblant le contrôleur de vue fractionné. La nouvelle collection trait remplace la HorizontalSizeClass
valeur , la définissant Regular
sur , afin que le contrôleur de vue fractionné affiche à la fois les vues maître et détail sur un i Téléphone dans l’orientation paysage.
Notez que le VerticalSizeClass
paramètre a été défini unspecified
sur , ce qui permet à la nouvelle collection Trait d’être ajoutée à la collection Trait sur le parent, ce qui entraîne l’ajout d’un Compact VerticalSizeClass
contrôleur de vue fractionné enfant.
Modifications des caractéristiques
Cette section examine en détail la façon dont les collections de traits passent lorsque l’environnement trait change. Par exemple, lorsque l’appareil est pivoté du portrait au paysage.
Tout d’abord, iOS 8 effectue une configuration pour préparer la transition. Ensuite, le système anime l’état de transition. Enfin, iOS 8 propre s-up tous les états temporaires requis pendant la transition.
iOS 8 fournit plusieurs rappels que le développeur peut utiliser pour participer à la modification des caractéristiques, comme indiqué dans le tableau suivant :
Phase | Rappel | Description |
---|---|---|
Programme d’installation |
|
|
Animation | WillTransitionToTraitCollection |
Le coordinateur de transition qui est passé à cette méthode a une AnimateAlongside propriété qui permet au développeur d’ajouter des animations qui seront exécutées avec les animations par défaut. |
Nettoyage | WillTransitionToTraitCollection |
Fournit une méthode permettant aux développeurs d’inclure leur propre code de propre up une fois la transition effectuée. |
La WillTransitionToTraitCollection
méthode est idéale pour animer les contrôleurs de vue ainsi que les modifications apportées à la collection Trait. La WillTransitionToTraitCollection
méthode est disponible uniquement sur les contrôleurs d’affichage ( UIViewController
) et non sur d’autres environnements de caractéristiques, comme UIViews
.
Il TraitCollectionDidChange
est idéal pour travailler avec la UIView
classe, où le développeur souhaite mettre à jour l’interface utilisateur à mesure que les caractéristiques changent.
Réduction des contrôleurs de vue fractionnés
Examinons maintenant plus en détails ce qui se passe lorsqu’un contrôleur de vue fractionné se réduit d’une colonne à une vue de colonne. Dans le cadre de cette modification, deux processus doivent se produire :
- Par défaut, le contrôleur de vue fractionné utilise le contrôleur de vue principal comme vue après la réduction. Le développeur peut remplacer ce comportement en remplaçant la
GetPrimaryViewControllerForCollapsingSplitViewController
méthode du contrôleur deUISplitViewControllerDelegate
vue et en fournissant n’importe quel contrôleur de vue qu’il souhaite afficher dans l’état réduit. - Le contrôleur de vue secondaire doit être fusionné dans le contrôleur de vue principal. En règle générale, le développeur n’a pas besoin d’entreprendre d’action pour cette étape ; Le contrôleur de vue fractionné inclut la gestion automatique de cette phase en fonction de l’appareil matériel. Toutefois, il peut y avoir certains cas particuliers où le développeur souhaite interagir avec cette modification. L’appel de la
CollapseSecondViewController
méthode permet au contrôleur deUISplitViewControllerDelegate
vue maître d’être affiché lorsque l’effondrement se produit, au lieu de la vue détails.
Développement du contrôleur de vue fractionné
Examinons maintenant plus en détails ce qui se passe lorsqu’un contrôleur de vue fractionné est développé à partir d’un état réduit. Une fois de plus, deux étapes doivent se produire :
- Tout d’abord, définissez le nouveau contrôleur de vue principal. Par défaut, le contrôleur de vue fractionné utilise automatiquement le contrôleur d’affichage principal à partir de la vue réduite. Là encore, le développeur peut remplacer ce comportement à l’aide de la
GetPrimaryViewControllerForExpandingSplitViewController
méthode duUISplitViewControllerDelegate
. - Une fois le contrôleur de vue principal choisi, le contrôleur de vue secondaire doit être recréé. Là encore, le contrôleur de vue fractionné inclut la gestion automatique de cette phase en fonction de l’appareil matériel. Le développeur peut remplacer ce comportement en appelant la
SeparateSecondaryViewController
méthode duUISplitViewControllerDelegate
.
Dans un contrôleur de vue fractionné, le contrôleur de vue principal joue un rôle dans le développement et la réduction des vues en implémentant les méthodes et SeparateSecondaryViewController
les CollapseSecondViewController
méthodes du UISplitViewControllerDelegate
. UINavigationController
implémente ces méthodes pour envoyer (push) et afficher automatiquement le contrôleur de vue secondaire.
Affichage des contrôleurs
Une autre modification apportée par Apple à iOS 8 est la façon dont le développeur affiche les contrôleurs de vue. Dans le passé, si l’application disposait d’un contrôleur de vue feuille (par exemple, un contrôleur de vue table) et que le développeur a montré un autre (par exemple, en réponse à l’utilisateur appuyant sur une cellule), l’application revient à travers la hiérarchie du contrôleur de contrôleur vers le contrôleur de vue de navigation et appelle la PushViewController
méthode pour afficher la nouvelle vue.
Cela a présenté un couplage très serré entre le contrôleur de navigation et l’environnement dans lequel il s’exécutait. Dans iOS 8, Apple a découplé cela en fournissant deux nouvelles méthodes :
ShowViewController
: s’adapte pour afficher le nouveau contrôleur d’affichage en fonction de son environnement. Par exemple, dans un élémentUINavigationController
, il envoie simplement la nouvelle vue sur la pile. Dans un contrôleur de vue fractionné, le nouveau contrôleur d’affichage sera présenté sur le côté gauche en tant que nouveau contrôleur de vue principal. Si aucun contrôleur d’affichage conteneur n’est présent, la nouvelle vue s’affiche en tant que contrôleur d’affichage modal.ShowDetailViewController
: fonctionne de la même manière queShowViewController
, mais est implémenté sur un contrôleur de vue fractionné pour remplacer l’affichage des détails par le nouveau contrôleur de vue passé. Si le contrôleur d’affichage fractionné est réduit (comme indiqué dans une application i Téléphone), l’appel est redirigé vers laShowViewController
méthode, et la nouvelle vue s’affiche en tant que contrôleur d’affichage principal. Là encore, si aucun contrôleur d’affichage conteneur n’est présent, la nouvelle vue s’affiche en tant que contrôleur d’affichage modal.
Ces méthodes fonctionnent en commençant par le contrôleur de vue feuille et en parcourant la hiérarchie d’affichage jusqu’à ce qu’ils trouvent le contrôleur de vue conteneur approprié pour gérer l’affichage de la nouvelle vue.
Les développeurs peuvent implémenter ShowViewController
et ShowDetailViewController
dans leurs propres contrôleurs d’affichage personnalisés pour obtenir les mêmes fonctionnalités automatisées que celles qui UINavigationController
leur UISplitViewController
sont proposées.
Fonctionnement
Dans cette section, nous allons examiner la façon dont ces méthodes sont réellement implémentées dans iOS 8. Commençons par examiner la nouvelle GetTargetForAction
méthode :
Cette méthode guide la chaîne de hiérarchie jusqu’à ce que le contrôleur d’affichage de conteneur approprié soit trouvé. Par exemple :
- Si une
ShowViewController
méthode est appelée, le premier contrôleur de vue de la chaîne qui implémente cette méthode est le contrôleur de navigation. Il est donc utilisé comme parent de la nouvelle vue. - Si une
ShowDetailViewController
méthode a été appelée à la place, le contrôleur de vue fractionné est le premier contrôleur de vue à l’implémenter. Il est donc utilisé comme parent.
La GetTargetForAction
méthode fonctionne en localisant un contrôleur de vue qui implémente une action donnée, puis en demandant à ce contrôleur de vue s’il souhaite recevoir cette action. Étant donné que cette méthode est publique, les développeurs peuvent créer leurs propres méthodes personnalisées qui fonctionnent comme les méthodes intégrées ShowViewController
et ShowDetailViewController
les méthodes.
Présentation adaptative
Dans iOS 8, Apple a également fait des présentations popover ( UIPopoverPresentationController
) adaptatives. Par conséquent, un contrôleur d’affichage de présentation popover présente automatiquement une vue contextuelle normale dans une classe de taille régulière, mais l’affiche en plein écran dans une classe de taille compacte horizontalement (par exemple, sur un i Téléphone).
Pour prendre en charge les modifications dans le système de storyboard unifié, un nouvel objet de contrôleur a été créé pour gérer les contrôleurs de vue présentés . UIPresentationController
Ce contrôleur est créé à partir du moment où le contrôleur d’affichage est présenté jusqu’à ce qu’il soit ignoré. Comme il s’agit d’une classe de gestion, elle peut être considérée comme une super classe sur le contrôleur de vue, car elle répond aux modifications d’appareil qui affectent le contrôleur de vue (par exemple, l’orientation) qui sont ensuite renvoyées dans le contrôleur de vue les contrôles Du contrôleur de présentation.
Lorsque le développeur présente un contrôleur de vue à l’aide de la PresentViewController
méthode, la gestion du processus de présentation est transmise .UIKit
UIKit handles (entre autres) le contrôleur approprié pour le style créé, avec la seule exception étant lorsqu’un contrôleur de vue a le style défini UIModalPresentationCustom
sur . Ici, l’application peut fournir son propre PresentationController plutôt que d’utiliser le UIKit
contrôleur.
Styles de présentation personnalisés
Avec un style de présentation personnalisé, les développeurs ont la possibilité d’utiliser un contrôleur de présentation personnalisé. Ce contrôleur personnalisé peut être utilisé pour modifier l’apparence et le comportement de l’affichage auquel il est allié.
Utilisation des classes de taille
Le projet Xamarin Photos adaptatives inclus dans cet article donne un exemple de travail d’utilisation des classes de taille et des contrôleurs de vue adaptative dans une application d’interface unifiée iOS 8.
Bien que l’application crée complètement son interface utilisateur à partir du code, au lieu de créer un storyboard unifié à l’aide du Générateur d’interface de Xcode, les mêmes techniques s’appliquent.
Examinons maintenant plus en détail la façon dont le projet Photos adaptatives implémente plusieurs fonctionnalités de la classe taille dans iOS 8 pour créer une application adaptative.
Adaptation aux modifications de l’environnement trait
Lors de l’exécution de l’application Photos adaptatives sur un i Téléphone, lorsque l’utilisateur fait pivoter l’appareil du portrait vers le paysage, le contrôleur de vue fractionné affiche à la fois la vue maître et les détails :
Pour ce faire, substituez la UpdateConstraintsForTraitCollection
méthode du contrôleur de vue et ajustez les contraintes en fonction de la valeur du VerticalSizeClass
. Par exemple :
public void UpdateConstraintsForTraitCollection (UITraitCollection collection)
{
var views = NSDictionary.FromObjectsAndKeys (
new object[] { TopLayoutGuide, ImageView, NameLabel, ConversationsLabel, PhotosLabel },
new object[] { "topLayoutGuide", "imageView", "nameLabel", "conversationsLabel", "photosLabel" }
);
var newConstraints = new List<NSLayoutConstraint> ();
if (collection.VerticalSizeClass == UIUserInterfaceSizeClass.Compact) {
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|[imageView]-[nameLabel]-|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("[imageView]-[conversationsLabel]-|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("[imageView]-[photosLabel]-|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:|[topLayoutGuide]-[nameLabel]-[conversationsLabel]-[photosLabel]",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:|[topLayoutGuide][imageView]|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.Add (NSLayoutConstraint.Create (ImageView, NSLayoutAttribute.Width, NSLayoutRelation.Equal,
View, NSLayoutAttribute.Width, 0.5f, 0.0f));
} else {
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|[imageView]|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[nameLabel]-|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[conversationsLabel]-|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[photosLabel]-|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:[topLayoutGuide]-[nameLabel]-[conversationsLabel]-[photosLabel]-20-[imageView]|",
NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
}
if (constraints != null)
View.RemoveConstraints (constraints.ToArray ());
constraints = newConstraints;
View.AddConstraints (constraints.ToArray ());
}
Ajout d’animations de transition
Lorsque le contrôleur de vue fractionné dans l’application Photos adaptatives passe de réduit à développé, les animations sont ajoutées aux animations par défaut en remplaçant la WillTransitionToTraitCollection
méthode du contrôleur de vue. Par exemple :
public override void WillTransitionToTraitCollection (UITraitCollection traitCollection, IUIViewControllerTransitionCoordinator coordinator)
{
base.WillTransitionToTraitCollection (traitCollection, coordinator);
coordinator.AnimateAlongsideTransition ((UIViewControllerTransitionCoordinatorContext) => {
UpdateConstraintsForTraitCollection (traitCollection);
View.SetNeedsLayout ();
}, (UIViewControllerTransitionCoordinatorContext) => {
});
}
Substitution de l’environnement trait
Comme indiqué ci-dessus, l’application Photos adaptatives force le contrôleur d’affichage fractionné à afficher les détails et les affichages maîtres lorsque l’appareil i Téléphone est en mode paysage.
Pour ce faire, utilisez le code suivant dans le contrôleur de vue :
private UITraitCollection forcedTraitCollection = new UITraitCollection ();
...
public UITraitCollection ForcedTraitCollection {
get {
return forcedTraitCollection;
}
set {
if (value != forcedTraitCollection) {
forcedTraitCollection = value;
UpdateForcedTraitCollection ();
}
}
}
...
public override void ViewWillTransitionToSize (SizeF toSize, IUIViewControllerTransitionCoordinator coordinator)
{
ForcedTraitCollection = toSize.Width > 320.0f ?
UITraitCollection.FromHorizontalSizeClass (UIUserInterfaceSizeClass.Regular) :
new UITraitCollection ();
base.ViewWillTransitionToSize (toSize, coordinator);
}
public void UpdateForcedTraitCollection ()
{
SetOverrideTraitCollection (forcedTraitCollection, viewController);
}
Développement et réduction du contrôleur de vue fractionné
Examinons ensuite comment le comportement de développement et de réduction du contrôleur de vue fractionné a été implémenté dans Xamarin. Dans le AppDelegate
, lorsque le contrôleur de vue fractionné est créé, son délégué est affecté pour gérer ces modifications :
public class SplitViewControllerDelegate : UISplitViewControllerDelegate
{
public override bool CollapseSecondViewController (UISplitViewController splitViewController,
UIViewController secondaryViewController, UIViewController primaryViewController)
{
AAPLPhoto photo = ((CustomViewController)secondaryViewController).Aapl_containedPhoto (null);
if (photo == null) {
return true;
}
if (primaryViewController.GetType () == typeof(CustomNavigationController)) {
var viewControllers = new List<UIViewController> ();
foreach (var controller in ((UINavigationController)primaryViewController).ViewControllers) {
var type = controller.GetType ();
MethodInfo method = type.GetMethod ("Aapl_containsPhoto");
if ((bool)method.Invoke (controller, new object[] { null })) {
viewControllers.Add (controller);
}
}
((UINavigationController)primaryViewController).ViewControllers = viewControllers.ToArray<UIViewController> ();
}
return false;
}
public override UIViewController SeparateSecondaryViewController (UISplitViewController splitViewController,
UIViewController primaryViewController)
{
if (primaryViewController.GetType () == typeof(CustomNavigationController)) {
foreach (var controller in ((CustomNavigationController)primaryViewController).ViewControllers) {
var type = controller.GetType ();
MethodInfo method = type.GetMethod ("Aapl_containedPhoto");
if (method.Invoke (controller, new object[] { null }) != null) {
return null;
}
}
}
return new AAPLEmptyViewController ();
}
}
La SeparateSecondaryViewController
méthode teste pour voir si une photo est affichée et prend des mesures en fonction de cet état. Si aucune photo n’est affichée, elle réduit le contrôleur d’affichage secondaire afin que le contrôleur de vue maître soit affiché.
La CollapseSecondViewController
méthode est utilisée lors du développement du contrôleur de vue fractionnée pour voir si des photos existent sur la pile, si c’est le cas, elle est réduite à cette vue.
Déplacement entre les contrôleurs d’affichage
Examinons ensuite comment l’application Photos adaptatives se déplace entre les contrôleurs d’affichage. Dans la AAPLConversationViewController
classe lorsque l’utilisateur sélectionne une cellule dans le tableau, la ShowDetailViewController
méthode est appelée pour afficher la vue détails :
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
var photo = PhotoForIndexPath (indexPath);
var controller = new AAPLPhotoViewController ();
controller.Photo = photo;
int photoNumber = indexPath.Row + 1;
int photoCount = (int)Conversation.Photos.Count;
controller.Title = string.Format ("{0} of {1}", photoNumber, photoCount);
ShowDetailViewController (controller, this);
}
Affichage des indicateurs de divulgation
Dans l’application Photo adaptative, il existe plusieurs endroits où les indicateurs de divulgation sont masqués ou affichés en fonction des modifications apportées à l’environnement trait. Ceci est géré avec le code suivant :
public bool Aapl_willShowingViewControllerPushWithSender ()
{
var selector = new Selector ("Aapl_willShowingViewControllerPushWithSender");
var target = this.GetTargetViewControllerForAction (selector, this);
if (target != null) {
var type = target.GetType ();
MethodInfo method = type.GetMethod ("Aapl_willShowingDetailViewControllerPushWithSender");
return (bool)method.Invoke (target, new object[] { });
} else {
return false;
}
}
public bool Aapl_willShowingDetailViewControllerPushWithSender ()
{
var selector = new Selector ("Aapl_willShowingDetailViewControllerPushWithSender");
var target = this.GetTargetViewControllerForAction (selector, this);
if (target != null) {
var type = target.GetType ();
MethodInfo method = type.GetMethod ("Aapl_willShowingDetailViewControllerPushWithSender");
return (bool)method.Invoke (target, new object[] { });
} else {
return false;
}
}
Celles-ci sont implémentées à l’aide de la GetTargetViewControllerForAction
méthode décrite en détail ci-dessus.
Lorsqu’un contrôleur d’affichage de table affiche des données, il utilise les méthodes implémentées ci-dessus pour déterminer si un push va se produire ou non, et s’il faut afficher ou non l’indicateur de divulgation en conséquence :
public override void WillDisplay (UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
{
bool pushes = ShouldShowConversationViewForIndexPath (indexPath) ?
Aapl_willShowingViewControllerPushWithSender () :
Aapl_willShowingDetailViewControllerPushWithSender ();
cell.Accessory = pushes ? UITableViewCellAccessory.DisclosureIndicator : UITableViewCellAccessory.None;
var conversation = ConversationForIndexPath (indexPath);
cell.TextLabel.Text = conversation.Name;
}
Nouveau ShowDetailTargetDidChangeNotification
type
Apple a ajouté un nouveau type de notification pour l’utilisation des classes de taille et des environnements de caractéristiques à partir d’un contrôleur de vue fractionné. ShowDetailTargetDidChangeNotification
Cette notification est envoyée chaque fois que l’affichage détail cible d’un contrôleur de mode fractionné change, par exemple lorsque le contrôleur se développe ou s’réduit.
L’application Photos adaptatives utilise cette notification pour mettre à jour l’état de l’indicateur de divulgation lorsque le contrôleur d’affichage des détails change :
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
TableView.RegisterClassForCellReuse (typeof(UITableViewCell), AAPLListTableViewControllerCellIdentifier);
NSNotificationCenter.DefaultCenter.AddObserver (this, new Selector ("showDetailTargetDidChange:"),
UIViewController.ShowDetailTargetDidChangeNotification, null);
ClearsSelectionOnViewWillAppear = false;
}
Examinez plus en détail l’application Photos adaptatives pour voir toutes les façons dont les classes de taille, les collections de caractéristiques et les contrôleurs de vue adaptative peuvent être utilisés pour créer facilement une application unifiée dans Xamarin.iOS.
Storyboards unifiés
Nouveautés d’iOS 8, les storyboards unifiés permettent au développeur de créer un fichier de storyboard unifié qui peut être affiché sur les appareils i Téléphone et iPad en ciblant plusieurs classes de taille. En utilisant des storyboards unifiés, le développeur écrit moins de code spécifique à l’interface utilisateur et n’a qu’une seule conception d’interface pour créer et gérer.
Les principaux avantages des storyboards unifiés sont les suivants :
- Utilisez le même fichier storyboard pour i Téléphone et iPad.
- Déployez vers l’arrière sur iOS 6 et iOS 7.
- Affichez un aperçu de la disposition pour différents appareils, orientations et versions du système d’exploitation.
Activation des classes de taille
Par défaut, tout nouveau projet Xamarin.iOS utilise des classes de taille. Pour utiliser des classes de taille et des segues adaptatives à l’intérieur d’un storyboard à partir d’un projet plus ancien, il doit d’abord être converti au format de storyboard unifié Xcode 6 et la boîte de dialogue Utiliser les classes de taille case activée box est sélectionnée dans l’inspecteur de fichier Xcode pour vos storyboards.
Écrans de lancement dynamique
Le fichier d’écran de lancement s’affiche sous la forme d’un écran de démarrage pendant qu’une application iOS lance pour fournir des commentaires à l’utilisateur que l’application démarre réellement. Avant iOS 8, le développeur doit inclure plusieurs Default.png
ressources d’image pour chaque type d’appareil, orientation et résolution d’écran sur laquelle l’application s’exécuterait. Par exemple, Default@2x.png
, , Default-Portrait@2x~ipad.png
Default-Landscape@2x~ipad.png
, etc.
Factoring in the new i Téléphone 6 and i Téléphone 6 Plus devices (and the upcoming Apple Watch) with all the existing i Téléphone and iPad devices, this représente un large éventail de tailles, orientations et résolutions de ressources d’image d’écran de Default.png
démarrage qui doivent être créées et conservées. En outre, ces fichiers peuvent être assez volumineux et vont « gonfler » l’offre groupée d’applications livrables, augmentant la durée nécessaire pour télécharger l’application à partir de l’App Store iTunes (éventuellement l’empêcher de pouvoir être livré sur un réseau cellulaire) et augmenter la quantité de stockage requise sur l’appareil de l’utilisateur final.
Nouveautés d’iOS 8, le développeur peut créer un fichier atomique .xib
unique dans Xcode qui utilise la disposition automatique et les classes de taille pour créer un écran de lancement dynamique qui fonctionnera pour chaque appareil, résolution et orientation. Cela réduit non seulement la quantité de travail requise par le développeur pour créer et gérer toutes les ressources d’image requises, mais elle réduit considérablement la taille de l’ensemble installé de l’application.
Les écrans de lancement dynamique présentent les limitations et considérations suivantes :
- Utilisez uniquement
UIKit
des classes. - Utilisez une vue racine unique qui est un ou
UIViewController
unUIView
objet. - Ne créez aucune connexion au code de l’application (n’ajoutez pas d’actions ou de points de sortie).
- N’ajoutez pas d’objets
UIWebView
. - N’utilisez aucune classe personnalisée.
- N’utilisez pas d’attributs d’exécution.
Avec les instructions ci-dessus à l’esprit, examinons l’ajout d’un écran de lancement dynamique à un projet Xamarin iOS 8 existant.
Effectuez les actions suivantes :
Ouvrez Visual Studio pour Mac et chargez la solution pour ajouter l’écran de lancement dynamique à.
Dans le Explorateur de solutions, cliquez avec le bouton droit sur le
MainStoryboard.storyboard
fichier, puis sélectionnez Ouvrir avec>Xcode Interface Builder :Dans Xcode, sélectionnez Fichier>nouveau>fichier... :
Sélectionnez l’écran de lancement de l’interface>utilisateur iOS>, puis cliquez sur le bouton Suivant :
Nommez le fichier
LaunchScreen.xib
, puis cliquez sur le bouton Créer :Modifiez la conception de l’écran de lancement en ajoutant des éléments graphiques et en utilisant des contraintes de disposition pour les appareils, les orientations et les tailles d’écran données :
Enregistrez les changements apportés à
LaunchScreen.xib
.Sélectionnez la cible des applications et l’onglet Général :
Cliquez sur le bouton Choisir Info.plist , sélectionnez l’application
Info.plist
Xamarin, puis cliquez sur le bouton Choisir :Dans la section Icônes de l’application et Lancer des images, ouvrez la liste déroulante Lancer le fichier d’écran, puis choisissez le
LaunchScreen.xib
fichier créé ci-dessus :Enregistrez les modifications apportées au fichier et revenez à Visual Studio pour Mac.
Attendez que Visual Studio pour Mac terminer la synchronisation des modifications avec Xcode.
Dans le Explorateur de solutions, cliquez avec le bouton droit sur le dossier Ressource et sélectionnez Ajouter>des fichiers... :
Sélectionnez le
LaunchScreen.xib
fichier créé ci-dessus, puis cliquez sur le bouton Ouvrir :Générez l’application.
Test de l’écran de lancement dynamique
Dans Visual Studio pour Mac, sélectionnez le simulateur i Téléphone 4 Retina et exécutez l’application. L’écran de lancement dynamique s’affiche dans le format et l’orientation appropriés :
Arrêtez l’application dans Visual Studio pour Mac et sélectionnez un appareil iOS 8 iPad. Exécutez l’application et l’écran de lancement sera correctement mis en forme pour cet appareil et l’orientation :
Revenez à Visual Studio pour Mac et arrêtez l’exécution de l’application.
Utilisation d’iOS 7
Pour maintenir la compatibilité descendante avec iOS 7, incluez simplement les ressources d’image habituelles Default.png
comme normale dans l’application iOS 8. iOS revient au comportement précédent et utilise ces fichiers comme écran de démarrage lors de l’exécution sur un appareil iOS 7.
Résumé
Cet article a examiné rapidement les classes de taille et comment elles affectent la disposition dans les appareils i Téléphone et iPad. Il a abordé le fonctionnement des traits, des environnements traits et des collections de caractéristiques avec des classes de taille pour créer des interfaces unifiées. Il a pris un bref aperçu des contrôleurs de vue adaptative et comment ils fonctionnent avec des classes de taille à l’intérieur d’interfaces unifiées. Il a examiné l’implémentation complète des classes de taille et des interfaces unifiées à partir du code C# à l’intérieur d’une application Xamarin iOS 8.
Enfin, cet article a abordé les principes de base de la création d’un écran de lancement dynamique unique qui s’affiche en tant qu’écran de démarrage sur chaque appareil iOS 8.