While investigating a memory leak I discovered a problem related to the technique of calling setRootViewController:
inside a transition animation block:
[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];
If the old view controller (the one being replaced) is currently presenting another view controller, then the above code does not remove the presented view from the view hierarchy.
That is, this sequence of operations...
- X becomes Root View Controller
- X presents Y, so that Y's view is on screen
- Using
transitionWithView:
to make Z the new Root View Controller
...looks OK to the user, but the Debug View Hierarchy tool will reveal that Y's view is still there behind Z's view, inside a UITransitionView
. That is, after the three steps above, the view hierarchy is:
- UIWindow
- UITransitionView
- UIView (Z's view)
I suspect this is a problem because, at the time of the transition, X's view isn't actually part of the view hierarchy.
If I send dismissViewControllerAnimated:NO
to X immediately before transitionWithView:
, the resulting view hierarchy is:
- UIWindow
- UIView (X's view)
- UIView (Z's view)
If I send dismissViewControllerAnimated:
(YES or NO) to X, then perform the transition in the completion:
block, then the view hierarchy is correct. Unfortunately, that interferes with the animation. If animating the dismissal, it wastes time; if not animating, it looks broken.
I'm trying some other approaches (e.g., making a new container view controller class to serve as my root view controller) but haven't found anything that works. I'll update this question as I go.
The ultimate goal is to transition from the presented view to a new root view controller directly, and without leaving stray view hierarchies around.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…