user3117509
user3117509

Reputation: 833

Keep getting "Unbalanced calls to begin/end appearance transitions for <ViewController>" error

I have an app that is almost running perfectly. Here is how my app is structured:

6 total View Controllers on the storyboard. The first 3 View Controllers are the most important. The initial View Controller has buttons to "Login" and "Signup". The "Login" button modally presents a Login View Controller and the "Signup" button modally presents a Signup View Controller.

The Signup View Controller has 3 fields for username, password, and email and then a "submit" button. The submit button submits the data to my web server and if everything submits successfully it calls the "performSegueWithIdentifier" method on itself.

Here is the statement:

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

I spent 2 hours tonight trying to get the above method call to work and it finally does work. To get it to work, I had to select my Signup View Controller on the storyboard and go to Editor > Embed In > Navigation Controller (If I remember correctly I had to do this because the signup view controller is presented modally). I then dragged from my Signup View Controller's submit button to the View Controller I want to push to and selected Push and then typed in an identifier name.

Anyways, all of the above works perfectly fine until I try to use the back button on the View Controller that we pushed to using the method call. If I tap the back button, it goes to a 90% black screen with a blank nav bar at the top with a back button and of course that back button does nothing as well.

This is the error that I get in the console:

Unbalanced calls to begin/end appearance transitions for <VerificationViewController: 0x14ed1bb0>

Verification View Controller is the View Controller that the Signup View Controller pushes to via the performSegueWithIdentifier method.

Does anyone know how I can fix this error?

I have included a screenshot below of what my storyboard looks like in xcode. There is a view controller that I have coded but not connected yet and shouldn't make a difference anyways so you can ignore the View Controller to the right of the Login VC.

enter image description here

Upvotes: 23

Views: 46079

Answers (6)

anh hoang
anh hoang

Reputation: 56

I worked it and it is good for me Reason For Error : This message get displayed if you are pushing/presenting another View controller from TabBarController, Solution : please set viewController.modalPresentationStyle = .overCurrentContext, then present viewController topViewController.present(vc, animated: true, completion: nil)

Upvotes: 2

foram
foram

Reputation: 169

Reason For Error : This message get displayed if you are pushing/presenting another View controller from viewWillAppear,loadView,init or viewDidLoad method of current View Controller

Solution : Move your pushing/presenting code to viewDidAppear method will solve the issue

The reason is : in viewDidLoad not all of the fancy animations have already been finished, whereas in viewDidAppear everything's done.

Upvotes: 3

slobodans
slobodans

Reputation: 859

In my case this warning was caused by calling popToRootViewController of UINavigationController while modal view was displayed. When i moved popToRootViewController after modal view dismissed, warning stop to appear.

Upvotes: 3

CodeOverRide
CodeOverRide

Reputation: 4471

I solved this issue by wrapping in this.

dispatch_async(dispatch_get_main_queue()) {
    //call your performSegueWithIdentifier in here
}

Upvotes: 11

user3099609
user3099609

Reputation: 2318

In my case it was a subclass of UITabBarController with an overloaded setSelectedIndex: method that does the transition with an animation. I found that the following needs to be called before the animation start:

[sourceVC viewWillDisappear:YES];
[destinationVC viewWillAppear:YES];

And the following in the completion block:

if (finished) {
    [sourceVC viewDidDisappear:YES];
    [destinationVC viewDidAppear:YES];
    [super setSelectedIndex:selectedIndex];
}

The problem might still occur if multiple selectedIndex changes happen before animations end.

Upvotes: 3

user3117509
user3117509

Reputation: 833

I found the answer this morning in another stackoverflow question. The answer can be found here.

When I had originally setup the Push Segue, I clicked on and dragged from a button, and was also calling the performSegueWIthIdentifier method inside that button's IBAction method implementation. This was causing 2 identical push segues to be executed on the button press. I just left my method call in the IBAction, deleted the old push segue, and created a new push segue only this time I clicked on and dragged from the entire View Controller instead of it's button.

Upvotes: 12

Related Questions