Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0xa98e050>

32,044

Solution 1

I know this is an old question, but for the sake of those who run across this again, here is what I've found.

Firstly, The question does not state where the new viewController was being called.
I suspect this was called from -(void)viewDidLoad

Move the appropriate code to -(void)viewDidAppear: and the problem should go away.

This is because at -viewDidLoad, the view has loaded, but has not yet been presented and the animations and views have not completed.

If your intent is to push a window, do it after the window has been presented and has painted.

If you ever find yourself using timers to control system behavior, ask yourself what you are doing wrong, or how you could do it more properly.

Solution 2

I Found that this issue occurs if you trying to push new view controller while previous transaction (animation) in progress.

Anyway, i think, it is presentModalViewController problem, Set animated:NO, may be solve your problem

[(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:NO];

Other option is:

Take NSTimer and call above code between may be 0.50 to 1 second. This also helpful trick. so your pervious viewController has done its animation.

Solution 3

This warning appears when you try to load a new viewController before a previously included one is done animating. If your intention is to do that, simply add your code to a dispatch_async(dispatch_get_main_queue() block:

dispatch_async(dispatch_get_main_queue(), ^(void){
        [(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:YES];
});

and the warning will go away.

Solution 4

a modern solution may be this:

double delayInSeconds = 0.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds *   NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self.window.rootViewController presentViewController:yourVC animated:YES completion:nil];
});

Solution 5

You did not provide much context, so I assume this error is happening at startup since you are presenting a passcode view controller.

In order to get rid of this warning, I register the app delegate as a delegate of the navigation root view controller:

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ((UINavigationController *)self.window.rootViewController).delegate = self;
    return YES;
}

Then I present the modal view controller in navigationController:didShowViewController:animated: with a dispatch_once:

- (void) navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        KVPasscodeViewController *passcodeController = [[KVPasscodeViewController alloc] init];
        passcodeController.delegate = self;

        UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeController];
        [(UIViewController *)self.delegate presentViewController:passcodeNavigationController animated:YES completion:nil];
    });
}

Since navigationController:didShowViewController:animated: is called after the root view controller did appear, the Unbalanced calls to begin/end appearance transitions warning is gone.

Share:
32,044
KsK
Author by

KsK

Updated on March 02, 2020

Comments

  • KsK
    KsK about 4 years

    While compiling the code i got

    "Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0xa98e050>"

    warning.

    Here is my code

    KVPasscodeViewController *passcodeController = [[KVPasscodeViewController alloc] init];
    passcodeController.delegate = self;
    
    UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeController];
    [(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:YES];
    
  • user798719
    user798719 over 10 years
    yes I tried to introduce a timer; i just thought it was a hack but if this is the accepted solution....I was worried that I had something fundamentally wrong in my code, i.e., I wasn't doing it the proverbial apple way, hence the error.
  • wuf810
    wuf810 over 9 years
    Andreas. If there are "plenty of other, better ways" then why don't you specify them here. As it is your comment is not constructive.
  • Sententia
    Sententia over 9 years
    This is the right answer for me, and also explains in simple terms what is going on. I had done the same thing and presented a view modally before the animation of the previous view was finished.
  • Vineesh TP
    Vineesh TP over 9 years
    @Mark Travis: In my situation I can't call from 'viewDidAppear'. I am using ContainerViewClass and switching the view controller based on some action. This warning message always comes. stackoverflow.com/questions/27632106/…
  • drew..
    drew.. about 9 years
    This is the proper solution, and is even found to be required in at least one Apple demo, namely MyImagePicker, whereby the error message ViewController results in such a warning.
  • Isuru
    Isuru over 7 years
    I was indeed calling it in the viewDidLoad and moving that code in to the viewDidAppear resolved it. This is the correct answer.
  • David Kramf
    David Kramf over 6 years
    Using Xcode 9.1 and swift 4 and storyboardless project (I do everything programmatically ) I got the problem even when I presented a viewController from ViewDidAppear. Solved the issue with inserting the code of the presented controller ViewDidLoad inside async block DispatchQueue.main.asyncAfter(deadline: when) {}.