Reputation: 6825
This is my view (controller) hierarchy:
UITabBarController
(as the rootViewController
of the app)UINavigationController
(as the viewController
for one of the tabBar
tabs)UIViewController
(as the rootViewController
of the UINavigationController
)UICollectionView
(as a subview)MyViewController.view
(as a section header view of the UICollectionView
)And so, I need to present a modal view controller from MyViewController
. I have tried doing it with
[self presentViewController:modalVC animated:YES completion:nil];
and although it worked, Xcode warned me that "Presenting view controllers on detached view controllers is discouraged", and rightly so, because the modalVC only fills the view of the collection view header, which is not full screen which I'm after.
All other options that I have tried:
UITabBarController *tb = (UITabBarController *)self.view.window.rootViewController;
[tb presentViewController:modalVC animated:YES completion:nil];
or...
UINavigationController *nc = (UINavigationController *)tb.selectedViewController;
[tb presentViewController:modalVC animated:YES completion:nil];
or...
UICustomViewController *cv = (UICustomViewController *)nc.topViewController;
[vc presentViewController:modalVC animated:YES completion:nil];
present the modalVC full screen as desired, however, when I dismiss the modalVC by calling
[self dismissViewControllerAnimated:YES completion:nil];
from within modalVC itself, modalVC indeed dismisses itself, but I am left with a black screen. A little debugging revealed that after dismissing modalVC, self.view.window.rootViewController
becomes nil
.
Any idea why this is happening and how to resolve this?
EDIT
This is an iPhone app. The black screen happens on both iOS7 and iOS8. Also, below is the method where I initiate MyViewController
#pragma mark - UICollectionViewDelegate methods
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
self.myViewController = [[MyViewController alloc] initWithNibName:NSStringFromClass([MyViewController class]) bundle:nil];
return self.myViewController.view.frame.size;
}
Upvotes: 16
Views: 9225
Reputation: 35
I was facing a similar problem which was resolved by setting definesPresentationContext
to true
on the parent UIViewController
which presents the child UIViewController
modally (in my case I was presenting it overCurrentContext
).
Note - I don't know whether it is required to revert back the value of definesPresentationContext
after dismissing the child UIViewController
. I made provision to revert it back anyhow.
Upvotes: 0
Reputation: 1873
I had the black screen problem after presenting a screen with presentViewController:
and dismissing it with dismissViewControllerAnimated:
. My problem was that the dismiss command was unloading the entire view structure. My problem was resolved setting the modalPresentationStyle
to UIModalPresentationOverFullScreen
, as this:
viewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:viewController animated:YES completion:nil];
I got the solution from here.
Upvotes: 1
Reputation: 685
Is this an iPad app? If yes, adding
modalVC.modalPresentationStyle = UIModalPresentationFullScreen
before
[self presentViewController:modalVC animated:YES completion:nil];
in MyViewController
might do the trick.
Upvotes: 2
Reputation: 6825
I found the solution - this answer really helped. The trick was in dismissing the view controller. It should be done like this:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
and not like this:
[self dismissViewControllerAnimated:YES completion:nil];
Although the author of the linked answer suggests that a better approach would be to use delegation (presentED VC would define a protocol and presentING VC would subscribe to it and then dismiss the presentED VC once it asks for it), it wasn't feasible in my case.
Upvotes: 10
Reputation: 31
I find some information in Apple's UIViewController file
//The next two methods are replacements for presentModalViewController:animated and //dismissModalViewControllerAnimated: The completion handler, if provided, will be invoked after the presented controllers viewDidAppear: callback is invoked.
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0); // The completion handler, if provided, will be invoked after the dismissed controller's viewDidDisappear: callback is invoked.
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);
As you describled,you directly add view in UIViewController to another view . So viewDidAppear and viewDidDisappear are not invoked.I guess you'd better execute these two methods manually.
Upvotes: 0