J'ai découvert un comportement étrange dans mon application, où un connecté IBOutlet
a son cadre de vue connecté entre les appels dans mon contrôleur de vue à viewWillAppear:
et viewDidAppear:
. Voici le code pertinent dans ma UIViewController
sous - classe:
-(void)viewWillAppear:(BOOL)animated {
NSLog(@"%@", self.scrollView);
}
-(void)viewDidAppear:(BOOL)animated {
NSLog(@"%@", self.scrollView);
}
et la sortie de journal résultante:
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
Ce qui montre clairement que la trame change entre les deux appels. Je voulais faire la configuration avec la vue dans la viewDidLoad
méthode, mais si le contenu n'est pas disponible pour moi de changer jusqu'à ce qu'il soit à l'écran, cela semble assez inutile. Que pourrait-il se passer?
iphone
ios
objective-c
uiscrollview
Jumhyn
la source
la source
viewDidLayoutSubviews
était la bonne voie à suivre. Je devais juste mettre tout mon contenu dans une sous-vue pour que la méthode ne soit pas rappelée chaque fois que je changeais le cadre de la vue principale.Réponses:
Autolayout
fait un énorme changement dans la façon dont nous concevons et développons l'interface graphique de nos vues. L'une des principales différences est queautolayout
cela ne change pas la taille de nos vues immédiatement, mais seulement quand est déclenché, c'est-à-dire à un moment précis, mais nous pouvons le forcer à recalculer immédiatement nos contraintes ou à les marquer comme "nécessitant" une mise en page. Cela fonctionne comme-setNeedDisplay
.Le grand défi pour moi était de comprendre et d'accepter cela, nous n'avons plus besoin d'utiliser des masques de redimensionnement automatique, et le cadre est devenu une propriété inutile pour placer nos vues. Nous n'avons plus besoin de penser à la position des vues, mais nous devons réfléchir à la manière dont nous voulons les voir dans un espace lié les uns aux autres.
Lorsque nous voulons mélanger l'ancien masque de redimensionnement automatique et la mise en page automatique, c'est lorsque des problèmes surviennent. Nous devrions penser à l'implémentation de la disposition automatique très bientôt et essayer d'éviter de mélanger l'ancienne approche dans une hiérarchie de vues basée sur la disposition automatique.
C'est bien d'avoir une vue de conteneur qui n'utilise que des masques de redimensionnement automatique, comme une vue principale d'un contrôleur de vue, mais c'est mieux si nous n'essayons pas de mélanger.
Je n'ai jamais utilisé de storyboard, mais il est plus probable qu'il soit correct. Grâce à la mise en page automatique, le cadre de vos vues est défini lorsque le moteur de mise en page automatique commence son calcul. Essayez de demander la même chose juste après la super
- (void)viewDidLayoutSubviews
méthode de votre contrôleur de vue.Cette méthode est appelée lorsque le moteur de mise en page automatique a terminé de calculer les cadres de vos vues.
la source
add something on a screen, "just before it appears to the user". The actual answer is indeed to use viewDidLayoutSubviews.
... vous allez montrer cette vue plusieurs foisDe la documentation:
Avertit le contrôleur de vue que sa vue est sur le point d'être ajoutée à une hiérarchie de vues.
Avertit le contrôleur de vue que sa vue a été ajoutée à une hiérarchie de vues.
En conséquence, les cadres des sous-vues ne sont pas encore définis dans
viewWillAppear
:La méthode appropriée pour modifier votre interface utilisateur avant que la vue ne soit présentée à l'écran est:
Avertit le contrôleur de vue que sa vue vient de présenter ses sous-vues.
la source
viewDidLayoutSubviews
sera appelé plusieurs fois et pas toujours avec la même trame, (je pense que cela s'appelle parfois avec CGRectZero au premier appel). Il est appelé pour chaque sous-vue ajoutée et autres modifications de la vue.appel
dans votre
viewWillAppear
méthode. Ensuite, vous pouvez accéder à son cadre et il aura la même valeur que vous imprimez dansviewDidAppear
la source
Dans mon cas, déplacer toutes les méthodes liées au cadre vers
fonctionnait parfaitement (j'essayais de modifier les contraintes du storyboard).
la source