7
votes

In my application, I am presenting a modal view controller, but I'm having issues which I believe are caused by the fact that I am presenting the view controllers from a child view controller.

The call for presentViewController: animated: is coming from a view controller which is on the stack of a navigation controller, and that navigation controller is contained in another view controller using the "Container View" in Interface Builder. This outer container view controller has a persistent banner at the top of the screen.

When the view controller is presented, it animates the scroll up, and when it gets to the top, it goes underneath the banner of the container view controller. However, once the animation finishes it appears in front again, but no interaction is possible on the part of the modal view controller that would be covered by the banner. What is the proper way to present a modal view controller from a child view controller?

EDIT:

I've tried accessing the container view controller directly, which works at first, but once the modal view controller is dismissed the container view somehow expands to fill the entire screen, overlapping the entire banner.

EDIT:

Screenshot:

The modal view controller is sliding up and appearing underneath the banner at the top, then suddenly jumping to the front.

6
can you provide some screenshots? its hard for me to understand what youre try say.Bordz
Should the modal view controller be covered by the banner or not? It's not really clear.Erik B
The modal view controller should appear on top of the banner; It should behave like a modal view controller normally would.Jumhyn
So is the problem that it flashes to the front after animation or that no interaction is possible on the modal view controllers navbar or both?memmons
@Jumhyn I was unable to reproduce using the method you described. Trying presenting modally using a segue and from code, and both cases worked correctly. Something is missing from the description.Leo Natan

6 Answers

-1
votes

As discussed in the comments of the question, I tried reproducing the issue as described and couldn't. I think the problem was due to a messed up presentation of a view controller, which threw the system when attempting to present the modal view controller.

5
votes

I also encountered the issue: when calling: dismissViewControllerAnimated from a view controller presented modally from a child view controller, the child view controller is also dismissed.

After a bit of playing around in interface builder, I've managed to solve it.

Just change the modally presented view controller Presentation style to Over Full Screen. (the default is Full Screen)

Swift

// In the viewController class you're presenting modally
self.modalPresentationStyle = .overFullScreen

enter image description here

2
votes

You need to put these two methods in you AppDelegate and call these methods from where you want to present and dismiss modelviewconroller.

- (void)presentModelView{
    [[[[self.window rootViewController] navigationController] topViewController] presentViewController:controller animated:YES];
}

- (void)dismissModelView{
    [[[[self.window rootViewController] navigationController] topViewController] dismissViewControllerAnimated:YES completion:<#^(void)completion#>:controller animated:YES];
}
0
votes

I guess you could do something like:

[self.parentViewController presentViewController:controller animated:YES];

and if you need to present it from the parent of the parent you just call the same method on self.parentViewController.parentViewController

0
votes

Have you tried to calling the following from the ChildViewController object ?

[self presentModalViewController:viewController animated:YES];
-1
votes

You need to present the view controller from a view controller above the banner view. The simplest solution would be:

[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:controller animated:YES];

Caveat: This should work in most cases, but you'll have to be careful if the views you're modally presenting will themselves present other views modally, in which case you'll get an error because this view already has a presented controller. If this is the case, you could follow the chain of presented controllers by inspecting the presentedViewController property iteratively until you find a controller in which it is nil.