J'ai une vue personnalisée qui ne reçoit pas de layoutSubview
messages pendant l'animation.
J'ai une vue qui remplit l'écran. Il a une sous-vue personnalisée en bas de l'écran qui se redimensionne correctement dans Interface Builder si je change la hauteur de la barre de navigation. layoutSubviews
est appelé lorsque la vue est créée, mais plus jamais. Mes sous-vues sont correctement présentées. Si je désactive la barre d'état en cours d'appel, la sous-vue layoutSubviews
n'est pas appelée du tout, même si la vue principale anime son redimensionnement.
Dans quelles circonstances est layoutSubviews
effectivement appelé?
J'ai autoresizesSubviews
défini NO
pour ma vue personnalisée. Et dans Interface Builder, j'ai les entretoises supérieure et inférieure et l'ensemble de flèches verticales.
Une autre partie du puzzle est que la fenêtre doit être rendue clé:
[window makeKeyAndVisible];
sinon, les sous-vues ne sont pas automatiquement redimensionnées.
la source
layoutSubviews
. Est -ce que lainitWithFrame:
causelayoutSubviews
à appeler?view1.1
cela appellelayoutSubviews
deview1
puislayoutSubviews
deview1.1
. Cet appel ne se propage pas indéfiniment aux superviews, l'appelantview1.1.1
uniquementlayoutSubviews
sur les appels surview1.1
etview1.1.1
. Se déplacer sans changer sa taille ne fait appellayoutSubviews
à aucun d'entre eux.view1.2
enview1
,layoutSubviews
deview1.2
etview1
sont appelés, maislayoutSubviews
deview1.1
n'est pas appelé. (view1.1
etview1.2
sont des sous-vues deview1
). Autrement dit, toutes les sous-vues de la vue cible ne sont pas appeléeslayoutSubviews
méthode .Sur la base de la réponse précédente de @BadPirate, j'ai expérimenté un peu plus loin et j'ai apporté quelques clarifications / corrections. J'ai trouvé que ce
layoutSubviews:
sera appelé sur une vue si et seulement si:Quelques détails pertinents:
layoutSubviews:
est appelé chaque fois qu'un UIScrollView défile, car il effectue le défilement en changeant l'origine de ses limites.layoutSubviews:
quand la vue sera finalement ajoutée à une hiérarchie de vues .setNeedsLayout
, ce qui définit / lève un indicateur. À chaque itération de la boucle d'exécution, pour toutes les vues de la hiérarchie des vues , cet indicateur est vérifié. Pour chaque vue où le drapeau se trouve levé,layoutSubviews:
est appelé dessus et le drapeau est réinitialisé. Les vues plus haut dans la hiérarchie seront vérifiées / appelées en premier.la source
https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1
la source
Certains des points de la réponse de BadPirate ne sont que partiellement vrais:
Pour le
addSubView
pointCela dépend du masque de redimensionnement automatique de la vue (vue cible). Si le masque de redimensionnement automatique est activé, layoutSubview sera appelé sur chacun
addSubview
. S'il n'a pas de masque de redimensionnement automatique, alors layoutSubview sera appelé uniquement lorsque la taille du cadre de la vue (vue cible) change.Exemple: si vous avez créé UIView par programme (il n'a pas de masque de redimensionnement automatique par défaut), LayoutSubview sera appelé uniquement lorsque le cadre UIView ne change pas tous les jours
addSubview
.C'est grâce à cette technique que les performances de l'application augmentent également.
Pour le point de rotation de l'appareil
Cela ne peut être vrai que lorsque votre VC est dans la hiérarchie VC (racine à
window.rootViewController
), et bien c'est le cas le plus courant. Dans iOS 5, si vous créez un VC, mais qu'il n'est ajouté à aucun autre VC, ce VC ne sera pas remarqué lorsque l'appareil pivotera. Par conséquent, sa vue ne serait pas remarquée en appelant layoutSubviews.la source
J'ai trouvé la solution jusqu'à l'insistance d'Interface Builder sur le fait que les ressorts ne peuvent pas être modifiés sur une vue sur laquelle les éléments d'écran simulés sont activés (barre d'état, etc.). Étant donné que les ressorts étaient désactivés pour la vue principale, cette vue ne pouvait pas changer de taille et était donc défilée dans son intégralité lorsque la barre d'appel était apparue.
La désactivation des fonctions simulées, puis le redimensionnement de la vue et le réglage correct des ressorts ont provoqué l'animation et l'appel de ma méthode.
Un problème supplémentaire lors du débogage est que le simulateur quitte l'application lorsque l'état en cours d'appel est basculé via le menu. Quittez l'application = pas de débogueur.
la source
appeler
[self.view setNeedsLayout];
dans viewController permet d'appeler viewDidLayoutSubviewsla source
avez-vous regardé layoutIfNeeded?
L'extrait de documentation est ci-dessous. L'animation fonctionne-t-elle si vous appelez cette méthode explicitement pendant l'animation?
layoutIfNeeded Présente les sous-vues si nécessaire.
Discussion Utilisez cette méthode pour forcer la disposition des sous-vues avant de dessiner.
Disponibilité Disponible dans iPhone OS 2.0 et versions ultérieures.
la source
Lors de la migration d'une application OpenGL du SDK 3 vers 4, layoutSubviews n'était plus appelé. Après beaucoup d'essais et d'erreurs, j'ai finalement ouvert MainWindow.xib, sélectionné l'objet Window, dans l'inspecteur choisi l'onglet Attributs de fenêtre (le plus à gauche) et vérifié "Visible au lancement". Il semble que dans le SDK 3, il provoquait toujours un appel de layoutSubViews, mais pas dans 4.
6 heures de frustration terminées.
la source
Un cas assez obscur, mais potentiellement important, quand il
layoutSubviews
n'est jamais appelé est:la source