Modal UINavigationController hides although not di

2019-07-15 16:20发布

问题:

Okay, so I'm building an universal iOS app with an initial login view (view controller named LoginVC), just a plain simple UIViewController. If the login is successful the app segues to an navigation controller (MainNavigationVC). I created this segue through the storyboard gui of XCode, so no programmatic creation of the nav controller is done. The nav controller is presented modally in fullscreen, so the rest of the app is run atop the login view, with this nav controller as the centerpiece of everything.

The navigation controller contains a view (with a view controller named UserStartPageVC), and in its navigation bar is a logout button. This button sends an target action to UserStartPageVC, with the goal of dismissing the nav controller thus bringing the user back to the login view.

So far everything works fine. I can login and use the app as intended. But! When I log out and then re-login XCode tells me this:

Warning! Attempt to present <MainNavigationVC: 0x753110> on <LoginVC: 0x756fcf0> while a presentation is in progress!

I suppose this means that the login view is trying to modally display a MainNavigationVC navigation controller, but another one is already displayed, right? But how? Can a view be presented without showing?

And how can I get rid of the old nav controller when logging out? I've tried several ways of dismissing the modal view, for instance:

  • from within UserStartpageVC running

    [x dismissViewControllerAnimated:YES completion:NULL]

    [x dismissModalViewControllerAnimated:YES]

where x is either self, self.parentViewController or self.presentingViewController.

  • setting the LoginVC as a property in UserStartpageVC and running

    [self.loginVC dismissViewControllerAnimated:YES completion:NULL]

and so on.

All of the tested calls actually brings me back to the login screen, so it's kind of working.

Any ideas? Relevant code samples can be provided if necessary, I just couldn't figure out which pieces that were of interest. The seguing to the navigation controller has no code (except for a performSegueWithIdentifier:sender:), and the code for dismissing it is the part I cannot seem to get straight.

As a sidenote. So far this isn't a REAL problem; the app runs, and it IS possible to logout and re-login without any other side-effects than an error message in XCode. But I suppose this will be a memory leak if users logout and login multiple times, and I'm not in the mood of an unnecessary rejection from Apple.

回答1:

I discovered another way to get the exact same error message. Lucky me!

If you created a segue at one point and had it tied to a button (click button -> new view) and then later give that segue a name and invoke it directly using

[self performSegueWithIdentifier:@"identifierName" sender:self];

then you can get this error because you can effectively trigger the segue twice. I thought making the button invoke an IBAction would turn off the segue I had set up in the first place, but apparently not. Hitting the button triggered the segue twice, but after I deleted the segue and re-created it as a manual segue on the view with the same identifier then I was able to invoke it via the above code and not get the warning message.



回答2:

Hoopla! My bad.

Seemed I had set up the notification observing from the login API call in a stupid way. For every time the user triggered a login (or re-login), it added itself as an observer for the notification; the result was that it performed one more segue for every time a login was done.

And doing multiple segues at the same time, is... well, obviously bad.