23

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

user3117509
  • 833
  • 3
  • 14
  • 32

6 Answers6

12

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.

Community
  • 1
  • 1
user3117509
  • 833
  • 3
  • 14
  • 32
  • I check my button, but it doesn;t have segue triggered, but it still cause Unbalanced calls to begin/end appearance transitions for, using custom segue – DeckyFx Dec 29 '14 at 05:45
  • Another common issue is not calling super.method in a UIViewController subclass. For example, MyViewController.viewWillAppear() did not call super.viewWillAppear() and resulted in this error because internal view state had not been updated. – parleer Dec 20 '16 at 16:28
11

I solved this issue by wrapping in this.

dispatch_async(dispatch_get_main_queue()) {
    //call your performSegueWithIdentifier in here
}
CodeOverRide
  • 4,431
  • 43
  • 36
  • Terrific! Used this technique in the context of modally presenting a "lock screen" view controller via `presentViewController(_:animated:completion)` over a base (root) view controller from within `AppDelegate applicationDidBecomeActive(_:)`...before that root view controller's window hierarchy had been fully established. No longer have to defer presentation until the root controller's `viewDidLoad(animated:)`...an ugly decoupling of view management. Thanks! – Kevin Owens Aug 05 '16 at 18:01
  • amazing fix! was getting this when calling `popViewController(animated:)` – Charlton Provatas Nov 17 '17 at 19:34
3

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.

user3099609
  • 2,318
  • 18
  • 20
  • I'm not sure if this is the case, but you may want to use addChildViewController and removeFromParentController functions (and others) as described in Apple docs about UIViewController containers: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html – Jeroen Bouma Nov 25 '15 at 18:02
  • I had the same issue and solve in swift with this: http://stackoverflow.com/a/37096645/4483716 hope can help for someone. – Dasoga May 08 '16 at 05:45
  • 1
    This idea helped me with unbalanced transition errors when animating UITabBarController page changes. I was also able to use `beginAppearanceTransition` and `endAppearanceTransition` methods instead of directly calling `viewWillDisappear`/`viewWillAppear` and `viewDidDisappear`/`viewDidAppear`. The documentation for the appearance transition methods suggests not invoking `viewWillAppear`, etc. directly for child views. – Undrea Jun 28 '17 at 21:57
3

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.

slobodans
  • 859
  • 1
  • 17
  • 23
3

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.

foram
  • 169
  • 5
2

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)

anh hoang
  • 56
  • 3
  • I had a problem with presenting a VC as the very first thing on launch on top of my Tabbar. Setting the presentations style to over current context removed the error of unbalanced call on my tabbar controller. Thanks anh. Voted your post as useful. –  Aug 03 '21 at 06:51