UINavigationController 'corrupted navigation bar' issue

10,920

Solution 1

I finally figured out the problem.

performSegueWithIdentifier was being called before viewDidAppear was called on the LoadingViewController. A synchronisation error basically.

Solution 2

You should not perform segue in viewDidLoad. Try performing in viewDidApperar:

Apple documentation:

Displaying a View Controller’s Contents Programmatically … Present it from another visible view controller. …

Share:
10,920
Michael
Author by

Michael

Updated on June 05, 2022

Comments

  • Michael
    Michael almost 2 years

    I'm having serious problems getting my navigation controller to work and have tried pretty much every related question on this website.

    My problem is that when I perform a segue programmatically, there appears to be a transition in the navigation bar, but the view doesn't change. I see the following errors instead:

    2013-10-22 13:47:30.059 App[2236:a0b] nested push animation can result in corrupted navigation bar
    2013-10-22 13:47:30.411 App[2236:a0b] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
    2013-10-22 13:47:30.501 App[2236:a0b] Unbalanced calls to begin/end appearance transitions for 
    

    My storyboard looks like this:

    enter image description here

    In LoginViewController we perform a segue based on some condition:

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear];
        NSString* appState = [AppConfig getAppState];
        if ([appState isEqualToString:APP_STATE_WAITING]) {
            [self performSegueWithIdentifier:@"Load" sender:self];
        }
        else if ([appState isEqualToString:APP_STATE_REGISTRATION_AVAILABLE]) {
            [self performSegueWithIdentifier:@"SignUp" sender:self];
        }
    }
    

    In LoadingViewController we wait for a response from a web service before doing:

    - (void)segueToWaitingList:(NSUInteger)behind inFront:(NSUInteger)inFront
    {
        [MosaycOptions setAppState:APP_STATE_WAITING];
        dispatch_async(dispatch_get_main_queue(), ^{
             [self performSegueWithIdentifier:@"Waiting" sender:self];
        });
    }
    

    And it is that segue that gives me the problem. The nav bar transitions but the view does not and we see the following errors printed out:

    2013-10-22 13:47:30.059 App[2236:a0b] nested push animation can result in corrupted navigation bar
    2013-10-22 13:47:30.411 App[2236:a0b] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
    2013-10-22 13:47:30.501 App[2236:a0b] Unbalanced calls to begin/end appearance transitions for 
    

    The app doesn't crash, but no segue occurs, it doesn't transition to the waiting list view but simply stays on Loading and prints the error to console. When I press back rather than moving back to the login screen I get the following blank screen:

    enter image description here

    If I press back again it crashes with this error: http://pastebin.com/7mCyeQv9

    Something is clearly getting messed up with the navigation stack, however i've inspected it using the debugger and it looks absolutely fine, everything gets pushed as normal. I can't for the life of me figure it out. This is just a standard navigation controller setup that i've used before.

    Any ideas?

  • Michael
    Michael over 10 years
    Didn't help I'm afraid.
  • Michael
    Michael over 10 years
    I moved it into viewDidAppear but get the same issue.
  • Tom Testicool
    Tom Testicool almost 10 years
    How did you reconcile this?
  • Michael
    Michael almost 10 years
    From what I remember there was a race condition between a network response kicking off a segue and the viewDidAppear method of the transitioning view being called. I think I just had two booleans, one indicating that the response had been received and one indicating viewDidAppear had been called and then used those to decide whether top kick off the segue.