En enquêtant sur une fuite de mémoire, j'ai découvert un problème lié à la technique d'appel setRootViewController:
à l' intérieur d'un bloc d'animation de transition:
[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];
Si l'ancien contrôleur de vue (celui en cours de remplacement) présente actuellement un autre contrôleur de vue, le code ci-dessus ne supprime pas la vue présentée de la hiérarchie de vues.
Autrement dit, cette séquence d'opérations ...
- X devient le contrôleur de vue racine
- X présente Y, de sorte que la vue de Y soit à l'écran
- Utilisation
transitionWithView:
pour faire de Z le nouveau contrôleur de vue racine
... semble OK pour l'utilisateur, mais l'outil Hiérarchie des vues de débogage révélera que la vue de Y est toujours là derrière la vue de Z, à l'intérieur d'un UITransitionView
. Autrement dit, après les trois étapes ci-dessus, la hiérarchie des vues est:
- UIWindow
- UITransitionView
- UIView (vue de Y)
- UIView (vue de Z)
- UITransitionView
Je soupçonne que c'est un problème car, au moment de la transition, la vue de X ne fait pas partie de la hiérarchie des vues.
Si j'envoie dismissViewControllerAnimated:NO
à X immédiatement avant transitionWithView:
, la hiérarchie de vue résultante est:
- UIWindow
- UIView (vue de X)
- UIView (vue de Z)
Si j'envoie dismissViewControllerAnimated:
(OUI ou NON) à X, puis que j'effectue la transition dans le completion:
bloc, la hiérarchie de la vue est correcte. Malheureusement, cela interfère avec l'animation. Si vous animez le licenciement, cela fait perdre du temps; sinon animée, elle a l'air cassée.
J'essaie d'autres approches (par exemple, créer une nouvelle classe de contrôleur de vue de conteneur pour servir de contrôleur de vue racine) mais je n'ai rien trouvé qui fonctionne. Je mettrai à jour cette question au fur et à mesure.
Le but ultime est de passer directement de la vue présentée à un nouveau contrôleur de vue racine, et sans laisser de hiérarchies de vues parasites.
UIWindow
est la chose à faire, mais je n'ai pas eu le temps d'expérimenter beaucoup.