2017-09-19 1 views
38

J'ai commencé à adapter mon application pour iPhone X et j'ai trouvé un problème dans Interface Builder. Les guides de mise en page de zone de sécurité sont censés être rétrocompatibles, selon les vidéos officielles d'Apple. J'ai trouvé que cela fonctionne très bien dans les storyboards.Guides de disposition de zones de sécurité dans les fichiers xib - iOS 10

Mais dans mes fichiers XIB, les guides de mise en page de zone de sécurité ne sont pas respectés dans iOS 10.

Ils fonctionnent très bien pour la nouvelle version du système d'exploitation, mais les appareils iOS 10 semblent supposer simplement la distance de zone de sécurité zéro (en ignorant la taille de la barre d'état).

Ai-je manqué une configuration requise? Est-ce un bug Xcode, et si oui, toutes les solutions de contournement connues?

Voici une capture d'écran de la question dans un projet de test (iOS gauche 10, droite iOS 11):

safe area alignment on top of the screen

Répondre

41

Il y a quelques problèmes avec la mise en page de zone de sécurité et de compatibilité ascendante. Voir mon commentaire sur here.

Vous pouvez peut-être contourner les problèmes avec des contraintes supplémentaires comme une priorité 1000> = 20.0 à superview.top et une priorité 750 == safearea.top. Si vous affichez toujours une barre d'état, cela devrait corriger les choses.

Une meilleure approche peut être d'avoir des storyboards/xibs séparés pour pré-iOS 11 et iOS-11 et plus, surtout si vous rencontrez plus de problèmes que cela. La raison qui est préférable est parce que pré-iOS 11, vous devez mettre en place des contraintes pour les guides de mise en page haut/bas, mais pour iOS 11, vous devez les exposer à des zones de sécurité. Les guides de mise en page sont partis. La mise en page des guides de mise en page pour pré-iOS 11 est stylistiquement meilleure que juste compenser par un minimum de 20 pixels, même si les résultats seront les mêmes IFF vous montrez toujours une barre d'état. Si vous adoptez cette approche, vous devez définir chaque fichier sur la bonne cible de déploiement sur laquelle il sera utilisé (iOS 11 ou quelque chose de plus ancien) afin que Xcode ne vous avertisse pas et vous permette de: utiliser des guides de mise en page ou des zones de sécurité, selon. Dans votre code, vérifiez iOS 11 à l'exécution, puis chargez le storyboard/xibs approprié. L'inconvénient de cette approche est la maintenance (deux contrôleurs de vue doivent être maintenus et synchronisés), mais une fois que votre application ne prend en charge que iOS 11+ ou qu'Apple corrige la génération de contraintes du guide de disposition de rétrocompatibilité. , vous pouvez vous débarrasser des versions pré-iOS 11. Par ailleurs, comment affichez-vous le contrôleur avec lequel vous voyez cela? Est-ce juste le contrôleur de vue racine ou l'avez-vous présenté, ou ..? Le problème que j'ai remarqué a à voir avec le fait de pousser les contrôleurs de vue, de sorte que vous pouvez frapper un cas différent.

+0

Mon problème spécifique est uniquement sur les fichiers XIB, et semble se produire à la fois pour les contrôleurs poussés et présentés. Votre solution de contournement avec plusieurs contraintes semble être une bonne solution pour la plupart des situations. Merci! J'espère toujours qu'ils vont résoudre ces problèmes avant l'arrivée de l'iPhoneX. –

+0

Très merci pour la suggestion prioritaire! Fonctionne maintenant comme un charme sur iOS 9 et iOS 11 sous iPhone X. –

+0

Puis-je commenter poser cette question "Si vous montrez toujours une barre d'état, cela devrait réparer les choses."? Je ne vois pas comment afficher la barre d'état sur le simulateur de l'iPhone X en mode paysage. Ensuite, la solution de contournement décrite de «1000 priorité> = 20.0 à superview.top et une priorité de 750 == safearea.top» aurait un écart de 20px sur le dessus pour l'iPhone X en mode paysage. Ma solution consistait à supprimer la contrainte de "1000 priority> = 20.0" dans viewDidLoad si iOS <11. Ai-je manqué la manière de forcer la barre d'état dans l'iPhone X paysage? –

-3

trouvé la solution plus simple - il suffit de désactiver safe area et utiliser topLayoutGuide et bottomLayoutGuide + ajouter des correctifs pour iPhone X. Peut-être que ce n'est pas belle solution, mais nécessite moins d'efforts que possible

0

J'ai fini par supprimer la contrainte zone de sécurité que j'avais dans mon fichier xib. Au lieu de cela j'ai fait un exutoire à l'UIView en question, et à partir du code je l'ai accroché comme ça, dans viewDidLayoutSubviews.

let constraint = alert.viewContents.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor, constant: 0) 
constraint.priority = 998 
constraint.isActive = true 

Cela correspond une petite « alerte » en haut de l'écran, mais fait en sorte que le contenu voir à l'intérieur de l'alerte est toujours en dessous du haut zone de sécurité (iOS11ish)/topLayoutGuide (iOS10ish)

simple et solution unique. Si quelque chose casse, je serai de retour.

1

Actuellement, la rétrocompatibilité ne fonctionne pas correctement.

Ma solution est de créer 2 contraintes dans le générateur d'interface et de supprimer une fonction de la version ios que vous utilisez:

  • pour ios 11: view.top == safe area.top
  • pour les versions antérieures: view.top == superview.top + 20

Ajoutez-les en tant que points de vente, respectivement myConstraint et myConstraintIOS10. Puis:

override func viewDidLoad() { 
    if #available(iOS 11.0, *) { 
     view.removeConstraint(myConstraintIOS10) 
    } else { 
     view.removeConstraint(myConstraint) 
    } 
}