No pop animation in iOS 13

2020-02-15 ios objective-c uinavigationcontroller

I have an old app that I'm trying to update to fix a bug that appeared in iOS 13. Unfortunately, updating to the iOS 13 SDK triggered several other bugs. I've fixed them all, mostly through tweaks to the info.plist file, except this one thing.

I'm using a standard UINavigationController to display a series of table views. When I click a table row, that triggers pushViewController:animated: to go to the next view. This looks fine and animates correctly, but the console shows the message "Unbalanced calls to begin/end appearance transitions" for the view that I'm leaving.

When I click the back button, or swipe from left to right on the view, the previous view appears immediately, with no animation. The console again shows the warning "Unbalanced calls to begin/end appearance transitions" for the outgoing view. The navigation bar animates correctly, fading from the old view to the new view, but the view doesn't animate. I get the same behavior if I navigate back by swiping. In fact, if I swipe back very slowly, the view pops immediately when the swipe begins, rather than slowly dragging the old view into place as I move my finger.

I've found many posts where this happens when placing a navigation controller inside a tab bar controller, which I'm not doing, or when programmatically pushing views, which I'm not doing. I've checked that every override of viewWillAppear or viewDidAppear calls its superclass, and I have no mismatched calls (calling super viewDidAppear from viewWillAppear or vice versa).

I'm not using storyboards, just plain old objective C code with the pushViewController method. I do set up and place the navigation controller programmatically in a container view controller, like this:

MainMenu *rootViewController = [[MainMenu alloc] initWithNibName:@"MainMenu" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navigationController.delegate = self;
[self addChildViewController:self.navigationController];
[self.navigationController didMoveToParentViewController:self];
[self.view addSubview:self.navigationController.view];

The app works perfectly when I run it on an iOS 12 device. The problem only occurs on an iOS 13 device. I have another app that uses the same structure and was originally built around the same time, but regularly updated for iOS releases, and it doesn't have the problem. I've compared every file and setting I can think of and can't find a relevant difference between the two apps.

Has anyone else seen this when updating for iOS 13?


To eliminate any issues from the container view, I temporarily changed the app to place the navigation controller directly into the window. So I now have this in application:DidFinishLaunchingWithOptions::

MainMenu *mainMenu = [[MainMenu alloc] initWithNibName:@"MainMenu" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:mainMenu];
[self.window addSubview:self.navigationController.view];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];

Then to eliminate any issues with the view controller I'm navigating to, I made a new nib containing only an empty view, and in MainMenu, when clicking a table row, I run this code:

UIViewController *viewController = [[UIViewController alloc] initWithNibName:@"Empty" bundle:nil];
[self.appDelegate.navigationController pushViewController:viewController animated:YES];

Then I click the system-provided back button in the top left corner, and the MainMenu reappears, but without the animation and with the same console message. I feel like this has something to do with my project settings, since the code is so simple and straightforward. I ran a diff between the project.pbxproj file from this project and a different project that doesn't have the problem, and there were differences for things like compiler settings or bitcode, but nothing seemed relevant to this issue.


There is more going on here than you are telling us about. I tried what you have described, using a navigation controller as a manually embedded view controller, and it works fine. As you can see, we animate Back in good order (I have turned on Slow Animations for clarity):

enter image description here

The "unbalanced transition" calls sound important, but you have provided no information for discovering what might be causing them.