wonder-mike
wonder-mike

Reputation: 3

UIViewController.presentModalViewController hangs indefinitely

I have 3 view controllers, VC1, VC2, and VC3, that are instantiated when the app starts. I want to present them modally in a loop, like this:

VC1 -> VC2 -> VC3 -> VC1

On each view controller, I'm presenting the next view controller like this:

[self presentModalViewController:nextViewController animated:TRUE];

The issue is when I execute that line from VC3, for presenting again the first view controller VC1, the app hangs and becomes completely unresponsive. As soon as that line is executed, I can see on Xcode CPU usage jumping from 0% to 99% and memory from 20MB to 1GB. I cannot even pause execution using the debugger, I can only quit the process. No errors on the console either.

My project doesn't have anything else, it's just these 3 view controllers, each with a button to present the next view controller in the loop.
Is this navigation flow not supported by the system or am I doing something wrong?

I tried doing the same thing using segues on the storyboard, and that works fine. But I need to understand why it doesn't work using UIViewController.presentModalViewController.

This is basically the code for each view controller:

#import "VC2.h"

@implementation VC2

- (IBAction)onNextButtonClicked:(id)sender {
    [self presentModalViewController:_nextViewController animated:TRUE];
}

@end

Upvotes: -1

Views: 96

Answers (1)

DonMag
DonMag

Reputation: 77690

Your post is lacking some details -- however...

I'm assuming you have your Storyboard / Segues setup like this:

enter image description here

That "works" -- well, it doesn't crash (right away) -- because each button is presenting a new instance of the next view controller.

If you cycle through your 3 "present" segues a couple times, then go into Debug View Hierarchy, it will look something like this:

enter image description here

When you try to do this via code, you stated:

"VC1, VC2, and VC3, that are instantiated when the app starts"

So, let's say you have _vc1, _vc2 and _vc3, and you present _vc1.

_vc1 then presents _vc2, which presents _vc3, which then tries to present _vc1. But, that instance of _vc1 is already in the view hierarchy, presenting _vc2 presenting _vc3 ... and you end up with (effectively) an infinite loop.

A "carousel of presents" is a bit of an unusual interface... but, if that's what your goal is, you'll need to take another approach.

One option would be to present a single view controller, which would instantiate and load the 3 VCs as child view controllers.

Each child's view would be overlaid. When you want to go from VC1 to VC2, you can simulate the presentation by:

  • align VC2's view's Top to "main" view's bottom
  • bring VC2's view to the front
  • animate VC2's view up to the Top

If you're interested, I posted a quick example of that approach here: https://github.com/DonMag/PresentCarousel

Upvotes: 0

Related Questions