Présentations d'écran modal modal dans iOS 13

Bonjour à tous!


Je m'appelle Ilya, je viens de Tinkoff.ru. J'ai traduit pour vous un article de Geoff Hackworth sur la façon dont le style de présentation modale a changé dans iOS 13, ce qu'il a affecté et comment fonctionne la compatibilité descendante avec les versions précédentes d'iOS et Xcode.


image


Présentation


Au moment d'écrire ces lignes, la WWDC 2019 touche à sa fin. Comme de nombreux développeurs pour iOS, je traite lentement toutes les nouvelles informations que Apple nous a fournies, et dans les semaines (et mois!) À venir, j'essaierai de regarder autant de vidéos que possible.
J'avais trois questions sur mes propres applications:


  • Mes applications actuelles fonctionnent sans problème sur iOS 13? Apple a une longue histoire de compatibilité descendante, basée sur la version de Xcode avec laquelle l'application a été créée. L'histoire montre que les applications créées dans Xcode 10 pour iOS 13 se comporteront comme si elles s'exécutaient sur iOS 12. Mais ce n'est pas toujours le cas.
  • Mes applications fonctionnent-elles lors de la construction avec Xcode 11 / iOS 13? Construire à l'aide des derniers outils permet à l'application de fonctionner d'une nouvelle manière, en contournant la compatibilité descendante avec les versions précédentes d'iOS. Quelque chose est cassé?
  • Quelles modifications peuvent / doivent être apportées pour améliorer le fonctionnement de mes applications ou profiter des nouvelles fonctionnalités iOS 13? Il s'agit de la plus grande tâche, et il faudra plus de temps pour étudier et mettre en œuvre. Cette étude fait l'objet d'un article séparé.

Je n'ai pas encore installé iOS 13 sur un appareil réel, mais je peux tester l'élément n ° 1 en installant des applications créées dans Xcode-10 sur le simulateur iOS 13.
Je travaille toujours sur le point 2, mais sur la base de mes tests initiaux et de la lecture de tweets d'autres développeurs faisant des découvertes similaires, j'ai trouvé un certain nombre de changements de comportement dans mes applications lors de la construction avec Xcode 11. J'ai beaucoup de vidéos à regarder et des informations pour l'assimilation, mais dans ce post, je veux me concentrer sur les changements immédiatement perceptibles et potentiellement destructeurs dans la présentation de l'UIViewController dans iOS 13.


Modifier le style de présentation modale par défaut


Par défaut, une présentation modale est désormais une «page» (feuille de page d'origine), plutôt qu'un plein écran. La documentation de modalPresentationStyle lit modalPresentationStyle suit:


La valeur par défaut est UIModalPresentationAutomatic pour iOS, à partir d'iOS 13.0, et UIModalPresentationFullScreen dans les versions précédentes.
Par défaut, UIViewController, si modalPresentationStyle défini comme modalPresentationStyle, utilise UIModalPresentationPageSheet, mais les contrôleurs système peuvent utiliser différents styles d'affichage pour UIModalPresentationAutomatic.

Les effets de ce changement sont différents pour l'iPhone et l'iPad.


Présentation modale sur iPhone


Les styles de présentation de Page Sheet, Form Sheet et Popover sur iPhone sont adaptés en plein écran, sauf si la méthode UIAdaptivePresentationControllerDelegate est utilisée pour empêcher l'adaptation. Par exemple, l'écran des paramètres peut être présenté dans le style de la feuille de formulaire, de sorte qu'il s'affiche en mode plein écran sur l'iPhone et sous une forme réduite sur l'iPad. Techniquement, l'apparence / l'adaptation dépend de la largeur. Les présentations Feuille de page / Feuille de formulaire / Popover sur les appareils Paysage iPhone Plus et XS Max ne couvrent pas tout l'écran car elles ont la largeur habituelle. L'apparence de l'iPad dépend de la taille du curseur et du mode multitâche.
Les captures d'écran suivantes montrent la présentation de la feuille de formulaire sur iPhone XS pour trois cas: construire dans Xcode 10 pour iOS 12, construire dans Xcode 10 pour iOS 13, construire dans Xcode 11 pour iOS 13.



La rétrocompatibilité d'iOS 12 avec iOS 13 pour la construction de Xcode 10 donne une vue plein écran. Le style de l'UITableView groupé a changé dans iOS 13 pour masquer l'espace au-dessus de la première section en l'absence de titre. Même la version de Xcode 10 / iOS 12 se comporte différemment lorsqu'elle est lancée sur iOS 13, ce qui n'est pas ce à quoi je m'attendais.
Le plus grand changement dans iOS 13, bien sûr, est l'affichage de la carte (d'origine. Apparence semblable à une carte). L'UIViewController a été réduit en taille et son sommet est encore légèrement visible derrière l'UIViewController nouvellement introduit. L'UIWindow derrière l'UIViewController racine est également un peu visible. Le fond noir de UIWindow est superbe par défaut, en particulier sur les appareils avec une encoche. Certaines de mes applications ont défini l'arrière-plan de UIWindow sur blanc (pour des raisons dont je ne me souviens plus), et cela semblait assez moche. Je l'ai rapidement corrigé!


Comportement d'UIViewController dans un nouveau style d'affichage modal


Si le UIViewController présenté montre un autre UIViewController, les cartes se chevauchent avec une belle animation. Notez que seul le dernier UIViewController affiché et un peu du précédent sont visibles:



Une autre différence de comportement potentiellement importante est ce qui arrive à la présentation (présentation originale) UIViewController. Une présentation plein écran (présentation plein écran) qui couvre complètement l'UIViewController supprimera l'UIViewController de la hiérarchie. Mais dans le cas de la nouvelle présentation de la carte, l'UIViewController doit rester dans la hiérarchie car elle est toujours visible. Cependant, bien que l'utilisateur ne puisse voir que deux UIViewController à la fois, l'affichage répété de l'UIViewController ne supprime pas l'UIViewController inférieur de la hiérarchie.


Redimensionnement


La nouvelle apparence de type carte signifie que l'UIViewController illustré n'est pas aussi grand sur iOS 13 qu'il l'est sur iOS 12:



Je veux un plein écran!


Une demande explicite d'afficher l'UIViewController en mode plein écran empêchera l'affichage de style carte. Cependant, cela peut perturber le comportement de l'application sur l'iPad. Veuillez ne pas être tenté de vérifier l'idiome de l'appareil et d'utiliser un style de présentation différent pour iPhone et iPad. Si les dernières années nous ont appris quelque chose, c'est que nous ne devons pas faire d'hypothèses basées sur les types d'appareils ou les tailles d'écran. Si vous souhaitez que l'iPad affiche la page / feuille de formulaire, mais que l'iPhone dispose du plein écran, vous pouvez utiliser UIAdaptivePresentationControllerDelegate pour vous adapter au mode plein écran dans des conditions de largeur compactes.


Présentation modale sur iPad


Feuilles de formulaire


Les écrans affichés dans le style de feuille de formulaire restent inchangés dans iOS 13:



Feuilles de page


Comme indiqué ci-dessus, le modalPresentationStyle par défaut dans iOS 13 est désormais une feuille de page. Sur iPad, la taille de l'UIViewController dans ce style a changé en orientation portrait et paysage:




Comme dans iOS 12, la restriction sur le «contenu lisible» (taille de contenu lisible d'origine) change de taille lors du changement de la catégorie de taille de contenu (catégorie de taille de contenu d'origine). La taille réelle semble différente sur iOS 12 et 13 dans certaines catégories de taille de contenu.
L'UIViewController lui-même, présenté dans le style de Page Sheet, augmente également sur iOS 13 avec une augmentation de la catégorie de taille de contenu. Voici la catégorie «Extra Extra Extra Large» (la taille maximale disponible sans inclure des tailles d'accessibilité plus grandes):




Autres types de présentation


La documentation de modalPresentationStyle lit modalPresentationStyle suit:


Par défaut, l'UIViewController définit l'UIModalPresentationAutomatic comme UIModalPresentationPageSheet, mais d'autres contrôleurs système peuvent définir l'UIModalPresentationAutomatic différemment.

Je ne suis pas sûr à 100% de toutes les règles pour "le reste des contrôleurs système", mais j'ai trouvé que l'affichage d'un modalPresentationStyle écran modalPresentationStyle sans définir modalPresentationStyle donne une vue d'ensemble de la carte:



Glissez pour ignorer


Un autre changement important qui affecte à la fois l'iPhone et l'iPad est que les écrans présentés de façon modale qui ne sont pas en mode plein écran (à l'exception des fenêtres contextuelles) peuvent être fermés de manière interactive en faisant glisser vers le bas. À ce moment, l'écran derrière revient en mode plein écran:



Notez que dans cet exemple, j'ai placé l'écran "À propos" dans le UINavigationController de l'écran des paramètres. Bien que l'UINavigationController n'affichait pas son contrôleur racine, une fermeture interactive était possible.


Ne me fouette pas, je t'en prie!


Si vous comptez sur l'utilisateur pour cliquer sur le bouton Terminer (ou sur un bouton similaire) ou revenir en haut de la pile du contrôleur de navigation pour fermer l'UIViewController affiché de façon modale, le nouveau comportement de balayage à fermer peut perturber votre application car votre gestionnaire de fermeture d'écran ne le fait pas. sera exécuté.
Par exemple, dans mon application Pomodoro Timer Pommie, un utilisateur peut accéder à un sous-écran de l'écran Paramètres et ajouter ou modifier un profil de minuterie (configuration des périodes de travail / pause pour un type de tâche spécifique):



Dans le cas de Pommie, je pense que c'est normal (et sûr) si l'utilisateur ferme tout l'écran des paramètres avec glisser. Les utilisateurs s'attendront probablement à pouvoir fermer l'écran en une seule fois, et je veux que mes applications fonctionnent correctement dans iOS 13. Cependant, je pense que sur l'écran "Ajouter / Modifier le profil de la minuterie", vous ne pouvez pas laisser l'utilisateur fermer l'écran en faisant glisser, car il y a un risque de perte de changement. L'utilisateur peut ne pas être tout à fait clair de ce qui se passera après une telle fermeture.
Une partie de la résolution de ce problème est la nouvelle isModalInPresentation UIViewController: isModalInPresentation . De la documentation:


modalInPresentation est défini lorsque vous souhaitez rendre l'écran modal. Lorsque cette option est activée, la présentation empêche la fermeture interactive et ignore les événements en dehors des limites de l'UIViewController jusqu'à ce que ce paramètre soit défini sur NO.

Pour obtenir le comportement similaire à iOS 12 pour mon écran Paramètres sur iOS 13, je pourrais simplement définir true sur la propriété isModalInPresentation du isModalInPresentation affiché. Si l'utilisateur essaie de glisser vers le bas pour le fermer, l'écran se déplacera un peu, mais résistera aux actions de l'utilisateur et ne sera pas fermé.
La propriété peut être modifiée à tout moment afin que vous puissiez, par exemple, autoriser la fermeture si l'utilisateur n'a pas encore apporté de modifications qui seront perdues s'il ne les a pas explicitement enregistrées. Mais une fois la modification effectuée, vous pouvez définir isModalInPresentation pour empêcher la fermeture par glissement. Cela obligera l'utilisateur à cliquer sur le bouton "Annuler" ou "Enregistrer".


Détection rapprochée


Comme indiqué précédemment, certaines applications peuvent avoir besoin d'exécuter du code lorsque l'UIViewController modifiable se ferme à l'aide des boutons Annuler, Terminer ou Enregistrer (autre que simplement le fermer). Par exemple, vous devrez peut-être redémarrer le chronomètre dans le jeu ou agir sur la base de certaines informations que l'utilisateur a modifiées. Ce code ne sera pas exécuté si l'utilisateur ferme l'écran en glissant. Votre bouton n'est pas enfoncé, donc son gestionnaire d'actions ne sera pas appelé. Cela peut perturber le comportement de votre application.
Le moyen le plus simple d'éviter ce problème consiste à empêcher la fermeture interactive à l'aide de isModalInPresentation. L'utilisateur devra appuyer sur un bouton pour fermer le contrôleur de vue, comme c'était le cas avant iOS 13. Mais il y a une autre façon ...
iOS 13 ajoute de nouvelles méthodes UIAdaptivePresentationControllerDelegate. Ils permettent à un autre objet (généralement un écran qui a montré qu'un autre écran était modal) de contrôler si la fermeture interactive est autorisée (une alternative à l'utilisation de isModalInPresentation ) et de recevoir des informations sur le début ou la fin d'une fermeture interactive. Ces méthodes sont bien documentées et clairement expliquées dans WWDC 2019 224: Moderniser votre interface utilisateur pour IOS 13 , à partir de la 15e minute. Veuillez noter que presentationControllerWillDismiss peut être appelé plusieurs fois si l'utilisateur commence à glisser pour fermer, change d'avis, puis glisse à nouveau. Dans la méthode presentationControllerDidDismiss , vous devez exécuter du code supplémentaire, qui est appelé lorsque vous appuyez sur le bouton "Annuler", "Terminer" ou "Enregistrer" (bien sûr, vous n'avez pas besoin de fermer l'écran illustré). Ces méthodes ne seront pas appelées si UIViewController est fermé par programme. Par conséquent, vous devrez toujours exécuter votre code dans le gestionnaire de boutons (ou dans votre propre délégué), ce qui provoque la fermeture même lorsque vous travaillez sur iOS 13.
Examinons la méthode déléguée presentationControllerDidAttemptToDismiss . Il sera appelé si l'utilisateur essaie de glisser pour fermer, mais isModalInPresentation a conduit au verrouillage de fermeture. Dans la vidéo avec WWDC, il est proposé d'afficher une liste d'actions avec la question de savoir si l'utilisateur souhaite annuler les modifications ou les enregistrer. Cela semble être une très bonne idée si l'UIViewController montré a les boutons Annuler et Enregistrer / Terminer: créer une nouvelle note, modifier les propriétés de l'objet, etc.
Je pense que pour un UIViewController imbriqué dans la pile de navigation avec les boutons Annuler et Enregistrer, c'est plus compliqué. Le code pour effectuer la sauvegarde se trouve probablement dans l'UIViewController, qui est un niveau plus haut sur la pile, et non dans l'objet qui implémente l' UIAdaptivePresentationControllerDelegate . Essayer de rediriger la sélection d'un utilisateur vers un objet qui peut effectuer la sauvegarde peut ne pas être tout à fait approprié. Dans mes propres applications, je pense que je vais simplement bloquer la fermeture des écrans qui nécessitent une action d'annulation / d'enregistrement explicite s'ils ne sont pas en haut de la pile de navigation.


Les ressources


La vidéo WWDC 2019 sera le meilleur endroit pour découvrir ce qui a changé dans iOS 13, quelles modifications vous devez apporter à vos applications pour qu'elles fonctionnent correctement lors de la construction dans Xcode 11, et quelles modifications vous pouvez apporter pour les améliorer afin de profiter des nouvelles fonctions. Voici quelques vidéos pour vous aider à démarrer:



Conclusion


Jusqu'à présent, je n'ai trouvé aucun problème avec mes applications créées dans Xcode 10 sous iOS 13. La compatibilité descendante fonctionne vraiment ici. J'ai été un peu surpris de voir un changement dans l'apparence d'une table groupée.
Les builds de Xcode 11 avaient besoin de quelques corrections mineures pour faire face aux modifications des représentations modales discutées dans cet article. Il y aura probablement des changements que je n'ai pas encore découverts.
Testez soigneusement vos présentations modales (en particulier avec les barres de recherche)! Décidez si vous souhaitez autoriser l'utilisateur à fermer les écrans modaux avec un balayage et utilisez isModalInPresentation pour obtenir le comportement nécessaire pour éviter la perte accidentelle de données due à un balayage erroné. Pour plus de flexibilité et de contrôle, utilisez UIAdaptivePresentationControllerDelegate .

Source: https://habr.com/ru/post/fr467969/


All Articles