Given the below code
self.view.backgroundColor = [UIColor yellowColor];
MyViewController *myVC = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil]
myVC.view.backgroundColor = [UIColor clearColor];
myVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:myVC animated:NO completion:nil];
What happens under the hood when we call presentViewController ? When myVC is visible I cannot see yellow color, then I checked myVC.view.superView in it's viewDidAppear method and it is UIWindow.
Q1. Is that mean until the modal window is up presentingViewController.view (self.view in above case) is removed from the View hierarchy and presentedViewController.view (myVC.view in above case) is added over UIWindow ?
Q2. What will be the case if myVC.modalPresentationStyle != UIModalPresentationFullScreen ?
Q3. Does iOS also remove all the views from UIWindow except presentedViewController.view until the full screen modal dialog is up for optimization ? If NO why not ?
First, let's discuss the case without animation.
Before calling present
:
rootViewController
view.After calling present:
rootViewController
's view but inside the window (window is a UIView
, too). This view is transparent, dims the presenting controler and blocks user interaction.There are some other views added in between the window and the presented controller's window. If you log your view hierarchy, you'll see classes named _ControllerWrapperView
or something similar. However, this has changed between iOS versions and you shouldn't rely on the view structure.
Note that that the modal controller can't ever be transparent because it is not direct subview of the window and the wrappers between the controller and the window are not transparent.
The animated case is almost the same. Only there are some fancy animations between the steps.
Edit 2: The answer was really a bit incorrect. There is a big difference between iPhone and iPad presented controllers.
On iPhone, the presented controllers are always displayed full screen and the presenting controllers are actually removed from the window.
On iPad, if the presented controller is not fullscreen (see UIModalPresentationStyle
), the presenting controller stays in the window.
Your questions:
Is that mean until the modal window is up presentingViewController.view (self.view in above case) is removed from the View hierarchy and presentedViewController.view (myVC.view in above case) is added over UIWindow ?
If the controller is full screen, then this claim is true. Otherwise, the presenting view controller stays there but the whole contents are overlapped by other views (even if they are semi-transparent). Also, there are always some views between the presented and the presenting controller views.
What will be the case if myVC.modalPresentationStyle != UIModalPresentationFullScreen ?
See the answer to the previous question - on iPhone, there would be no difference.
Does iOS also remove all the views from UIWindow except presentedViewController.view until the full screen modal dialog is up for optimization ? If NO why not ?
From my tests, only the presenting controller is removed from the window hierarchy. This is probably to optimize drawing performance. This is the only controller the system can safely remove. Removing any other view could cause problems (e.g. views that should be always visible).
Edit: If you want to make a transparent controller, you can:
+[UIView transition...]
)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With