Désormais, Interface Builder permet à l'utilisateur de modifier dynamiquement la taille de chaque contrôleur de vue dans le storyboard, afin de simuler la taille d'un certain appareil.
Avant cette fonctionnalité, l'utilisateur doit définir manuellement la taille de chaque contrôleur de vue. Ainsi, le contrôleur de vue était sauvegardé avec une certaine taille, qui était utilisée dans la fonction initWithCoder
pour définir le cadre initial.
Maintenant, il semble que initWithCoder
n'utilisez pas la taille définie dans le storyboard, et définissez une taille de 1000x1000 px pour la vue viewcontroller et toutes ses sous-vues.
Ce n'est pas un problème, car les vues doivent toujours utiliser l'une ou l'autre de ces solutions de mise en page :
-
autolayout, et toutes les contraintes disposeront correctement vos vues.
-
autoresizingMask, qui mettra en page chaque vue qui n'a pas de contrainte attachée à ( note les contraintes d'autolayout et de marge sont maintenant compatibles dans la même vue \o / ! )
Mais cette est un problème pour tous les éléments de mise en page liés à la couche de visualisation, tels que cornerRadius
puisque ni l'un ni l'autre autolayout ni masque de redimensionnement s'applique aux propriétés des couches.
Pour répondre à ce problème, la méthode courante est d'utiliser viewDidLayoutSubviews
si vous êtes dans le contrôleur, ou layoutSubview
si vous êtes dans une vue. A ce stade (n'oubliez pas d'appeler leur super
méthodes relatives), vous êtes à peu près sûr que tout le travail de mise en page a été fait !
Pretty sûr ? Hum... pas totalement, j'ai remarqué, et c'est pourquoi j'ai posé cette question, dans certains cas la vue a toujours sa taille 1000x1000 avec cette méthode. Je pense qu'il n'y a pas de réponse à ma propre question. Pour donner le maximum d'informations à ce sujet :
1- cela ne se produit que lors de la mise en place des cellules ! Dans UITableViewCell
& UICollectionViewCell
sous-classes, layoutSubview
ne sera pas appelé après les sous-vues seraient correctement disposées.
2- Comme l'a fait remarquer @EugenDimboiu (merci de upvoter sa réponse si elle vous est utile), appeler [myView layoutIfNeeded]
sur la vue secondaire qui n'a pas été mise en page, la mettra en page correctement juste à temps.
- (void)layoutSubviews {
[super layoutSubviews];
NSLog (self.myLabel); // 1000x1000 size
[self.myLabel layoutIfNeeded];
NSLog (self.myLabel); // normal size
}
3- A mon avis, c'est définitivement un bug. Je l'ai soumis au radar (id 28562874).
PS : Je ne suis pas de langue maternelle anglaise, donc n'hésitez pas à éditer mon post si ma grammaire doit être corrigée ;)
PS2 : Si vous avez une meilleure solution, n'hésitez pas à écrire une autre réponse. Je déplacerai la réponse acceptée.
1 votes
J'ai le même problème avec UIImageView - lorsque j'imprime, j'obtiens un étrange frame = (0 0 ; 1000 1000) ;. Je suis à l'intérieur d'un UITableViewCell, et une fois que j'ai rafraîchi le tableau, le cadre est ce que je m'attends à ce qu'il soit (également lorsque la cellule sort de la fenêtre et revient). Quelqu'un a-t-il une idée de la raison pour laquelle cela se produit (cadre bizarre par défaut) ?
4 votes
Je pense que le
(0, 0, 1000, 1000)
bound initialization est la nouvelle façon dont Xcode instancie les vues de IB. Avant Xcode8, les vues étaient créées avec leur taille configurée dans le xib, puis redimensionnées en fonction de l'écran juste après. Mais maintenant, il n'y a pas de taille configurée dans le document IB puisque la taille dépend de la sélection de votre appareil (en bas de l'écran). La vraie question est donc la suivante : existe-t-il un endroit fiable où l'on peut vérifier la taille finale des vues ?4 votes
Utilisez-vous des coins arrondis pour votre bouton ? Essayez d'appeler layoutIfNeeded() avant.
0 votes
Intéressant. J'utilisais en effet le cadre de vue pour calculer une bordure ronde. Même si cela ne répond pas à la question, cela fonctionne. C'est un bon conseil à garder à l'esprit. Merci !
0 votes
Je pense que j'ai des problèmes similaires pour mettre en place un bouton d'image à l'intérieur de la vue de droite d'un uitextfield. Je voulais définir la hauteur et la largeur du bouton image à la hauteur du champ texte afin qu'il conserve son rapport d'aspect et qu'il sorte du conteneur.