artooras
artooras

Reputation: 6825

Dismissing modal view controller results in a black screen

This is my view (controller) hierarchy:

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

Answers (5)

hsiraaH
hsiraaH

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

Doug
Doug

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

Klaus Thul
Klaus Thul

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

artooras
artooras

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

alla
alla

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

Related Questions