Depuis Xcode 8 et iOS10, les vues ne sont pas dimensionnées correctement sur viewDidLayoutSubviews
Il semble qu'avec Xcode 8, sur viewDidLoad
, tous les viewcontroller des sous-vues ont la même taille de 1000x1000. Chose étrange, mais bon, viewDidLoad
n'a jamais été le meilleur endroit pour dimensionner correctement les points de vue.
Mais viewDidLayoutSubviews
est!
Et sur mon projet actuel, j'essaie d'imprimer, de la taille d'un bouton:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSLog(@"%@", self.myButton);
}
Le journal affiche une taille de (1000x1000) pour myButton! Alors si je me connecte sur un bouton, cliquez, par exemple, le journal affiche une taille normale.
Je suis avec mise en page automatique.
Est-ce un bug?
- Ayant le même problème avec UIImageView - quand j'ai l'impression-je obtenir une image bizarre = (0 0; 1000 1000);. Je suis à l'intérieur d'un UITableViewCell, et une fois que j'actualise la tableview le cadre est ce que j'attends d'être (aussi lorsque la cellule est en dehors de la fenêtre d'affichage et revenir à nouveau). Quelqu'un a une idée pourquoi ce qui se passe (bizarre d'image par défaut) ?
- Je pense que le
(0, 0, 1000, 1000)
lié d'initialisation est la nouvelle façon de Xcode instanciant des vues de l'IB. Avant Xcode8, des vues ont été créés 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 définie dans l'IB depuis la taille dépend de votre sélection de l'appareil (au bas de l'écran). La vraie question est donc: est-il un endroit sûr où les points de vue taille finale a pu être vérifié? - êtes-vous à l'aide de coins arrondis pour votre bouton ? Essayez d'appeler layoutIfNeeded() avant.
- Intéressant. J'étais en effet en utilisant le point de vue image pour calculer un tour frontière. Même si il ne répond pas à la question, il ne fonctionne pas. Ses une bonne astuce pour garder à l'esprit. Merci!
- Je pense que je vais avoir des problèmes similaires de la configuration d'un bouton image à l'intérieur de la rightview d'un uitextfield. J'ai voulu régler la hauteur et la largeur de l'image bouton à la hauteur de la zone de texte de sorte qu'il a maintenu son ratio d'aspect et de retombées sur le récipient.
Vous devez vous connecter pour publier un commentaire.
Maintenant, Interface Builder permet à l'utilisateur de modifier dynamiquement la taille de chaque vue de contrôleurs dans la table de montage séquentiel, pour simuler la taille d'un périphérique de stockage.
Avant cette fonctionnalité, l'utilisateur doit définir manuellement chaque vue contrôleur de taille. Donc, l'avis du contrôleur a été enregistré avec une certaine taille, qui a été utilisé dans
initWithCoder
pour définir la trame initiale.Maintenant, il semble que
initWithCoder
ne pas utiliser la taille définie dans la table de montage séquentiel, et de définir un 1000x1000 px taille pour le viewcontroller view & tous ses sous-vues.Ce n'est pas un problème, parce que les points de vue doivent toujours utiliser un de ces disposition des solutions:
mise en page automatique, et toutes les contraintes de mise en page correctement votre point de vue
autoresizingMask, qui sera mise en page de chaque point de vue qui n'ont pas de contrainte rattaché (note de mise en page automatique et de la marge contraintes sont maintenant compatibles dans la même vue \o/!)
Mais ce est un problème pour tous les mise en page des trucs liés à la couche de la vue, comme
cornerRadius
, puisque ni mise en page automatique ni d'un redimensionnement automatique de masque s'applique aux propriétés de la couche.Pour répondre à ce problème, la façon la plus commune est d'utiliser
viewDidLayoutSubviews
si vous êtes dans le contrôleur, oulayoutSubview
si vous êtes dans une vue. À ce stade, (n'oubliez pas d'appeler leursuper
relative méthodes), vous êtes à peu près sûr que tous les mise en page des trucs qui a été fait!Assez sûr? Hum... pas tout à fait, je l'ai fait remarquer, et c'est pourquoi j'ai posé cette question, dans certains cas, le point de vue a toujours son 1000x1000 taille sur 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 - il se fait uniquement lors de la présentation des cellules! Dans
UITableViewCell
&UICollectionViewCell
sous-classes,layoutSubview
ne sera pas appelé après des sous-vues seraient correctement layed dehors.2 - Que @EugenDimboiu a fait remarquer (veuillez upvote sa réponse si utile pour vous), l'appel de
[myView layoutIfNeeded]
sur la non-layed dehors sous-vue sera mise correctement, juste à temps.3 - À mon avis, c'est vraiment un bug. Je l'ai soumis à radar (id 28562874).
PS: je ne suis pas anglais natif, donc n'hésitez pas à éditer mon message si ma grammaire devrait être corrigé 😉
PS2: Si vous avez une meilleure solution, n'hésitez pas à écrire une autre réponse. Je vais passer la accepté de répondre.
viewDidLoad
.viewDidLoad
n'a jamais été le lieu de lire unframe
parce que même avant, les points de vue n'ont pas été correctement dimensionnés à cette étape. À mon avis, le bug est toujours 1000 grande image danslayoutSubviews
ouviewDidLayoutSubviews
méthodes.layoutIfNeed
et devenait fou en raison d'unUITableViewCell
avec une sous-vue qui devait avoir un gradient deUIStackView
à l'intérieur d'unUICollectionViewCell
n'était pas de retour à une bonne hauteur au cours deviewDidLayoutSubviews
. L'appel delayoutIfNeeded
immédiatement corrigé le problème.Êtes-vous à l'aide de coins arrondis pour votre bouton ?
Essayez d'appeler
layoutIfNeeded()
avant.Solution: tout Envelopper à l'intérieur de
viewDidLayoutSubviews
dansDispatchQueue.main.async
.-viewDidLoad
... une étrange solution de contournementJe sais que ce n'était pas votre question exacte, mais j'ai rencontré un problème similaire où, comme sur la mise à jour de certains de mes points de vue ont été foiré en dépit d'avoir la bonne taille de cadre dans viewDidLayoutSubviews. Selon iOS 10 notes de Version:
Essentiellement vous ne pouvez pas appeler layoutIfNeeded sur un objet enfant de la Vue si vous utilisez translatesAutoresizingMaskIntoConstraints - appelons maintenant layoutIfNeeded doit être sur le superView, et vous pouvez encore appeler cela dans viewDidLayoutSubviews.
Si les cadres ne sont pas correctes dans layoutSubViews (qui ne le sont pas), vous pouvez expédier async un peu de code sur le thread principal. Cela donne au système le temps de faire la mise en page. Lorsque le bloc-vous de l'expédition est exécuté, les cadres ont leur propre taille.
Cette correction de l' (ridiculement ennuyeux) problème pour moi:
Modifier/Note: C'est pour un plein écran ViewController.
[super viewDidLayoutSubviews];
dans cette méthode, à cause de beaucoup de mise en page automatique des trucs fait par la vue elle-mêmeUIView
s. Mais si vous devez effectuer spécial pour le calcul sur un certain point de vue image, Eugen la réponse de travaux: appellayoutIfNeeded
sur elle. J'ai le sentiment ce n'est pas la meilleure solution, mais je n'ai toujours pas trouvé mieux.Fait
viewDidLayoutSubviews
aussi n'est pas le meilleur endroit pour mettre en image de votre point de vue. Que j'ai compris, à partir de maintenant, le seul endroit où il doit être fait estlayoutSubviews
méthode dans la vue de code. Je souhaite que je n'étais pas bon, quelqu'un me corriger s'il vous plaît si ce n'est pas vrai!viewDidLayoutSubviews
est assez ambigu. La deuxième phrase dans "discussions" contredit en quelque sorte le dernier. developer.apple.com/reference/uikit/uiviewcontroller/...Je l'ai déjà signalé ce problème à apple, ce problème existe depuis longtemps, lorsque vous sont en cours d'initialisation UIViewController de Xib, mais je l'ai trouvé assez sympa solution de contournement. En plus de cela, j'ai trouvé le problème dans certains cas, lorsque layoutIfNeeded sur UICollectionView et UITableView lorsque la source de données n'est pas définie dans le moment initial, et il fallait aussi de la swizzle il.
D'expédition une fois que l'extension:
Swizzle extension:
Mon problème a été résolu en modifiant l'utilisation de
à
Donc, de Fait, Va
Super bizarre
Meilleure solution pour moi.
À l'aide de
Remplacer layoutSublayers(de la couche: CALayer) au lieu de layoutSubviews dans la cellule sous-vue de corriger les images
Si vous avez besoin de faire quelque chose selon votre point de vue de l'image - remplacer layoutSubviews et appel layoutIfNeeded
J'ai eu le problème avec viewDidLayoutSubviews retour de la mauvaise image de mon point de vue, pour lequel j'ai besoin d'ajouter un dégradé. Et seulement layoutIfNeeded fait la bonne chose 🙂
Conformément à la nouvelle mise à jour en ios c'est effectivement un bug, mais nous pouvons réduire ce en utilisant -
Si vous utilisez xib avec mise en page automatique dans votre projet, vous avez juste à mise à jour cadre dans la mise en page automatique de réglage veuillez trouver l'image de ce .