Today I tried updating my Objective-C/Interface Builder based app to iOS 13, and none of my view controller transitions work anymore. Running in the Simulator, I get the error "Unbalanced calls to begin/end appearance transitions for.." followed by whatever view controller I just left. For example, if the current view controller is SettingsViewController and in response to a button press I do this:
EditCustVC *vc = [[ EditCustVC alloc] init];
[nc pushViewController:vc animated:NO];
Then I get the IB look of the EditCustVC, but viewDidAppear is never called for EditCustVC, and there is the error message: "Unbalanced calls to begin/end appearance transitions for SettingsViewController." Then if I dismiss EditCustVC like this:
[[self navigationController] popViewControllerAnimated:NO];
Then I return to the SettingsViewController, but without effect of viewDidAppear, and there is the error message: "Unbalanced calls to begin/end appearance transitions for EditCustVC." So the error message always refers to the view controller I am leaving, whether it is navigating forward with a pushViewController, or backward with a popViewController.
This may be a clue: When setting breakpoints in my main view controller (which is lauched from a Nib), the sequence of calls is:
awakeFromNib
viewWillDisappear
viewDidLoad
viewWillAppear
and viewDidAppear is never called. In view of the error message, the calling of viewWillDisappear before the view has appeared is highly suspicious. I should mention that this app is very complex and has been maintained since 2009 when I first released it. Many things have been added over the years, but the basic structure of launching the main view controller from a Nib, and then launching other view controllers and poping them as outlined above has never changed. It worked perfectly under iOS 12 and Xcode 10. But now that I have updated to Xcode 11 and the iOS 13 SDK, the expected sequence of calls just does not happen anymore. Since the app is quite complex at this point, it is really not feasible to totally overhaul the foundation of the app. I am looking for a minimal change that will work with the iOS 13 SDK, and still work with a deployment target of iOS 9. Does anyone have any suggestions?
It is also noteable that none of these problems result in crash as such. The program continues to run - after a fashion. It is just that the messed up order of calls and the absense of calls to viewDidAppear is making the app unusable. I will also note that when I select a simulator target with iOS 12, it runs perfectly.
Yes, I did, as follows:
The Main View Controller object in the Attribute Inspector showed Presentation: Automatic, which I changed to Full Screen.
Edit:
I found something that worked. In looking through my app delegate method, applicationDidFinishLaunching, I found this:
UINavigationController *nc = [[ UINavigationController alloc ] initWithRootViewController: mainViewController ];
self.navController = nc;
[window addSubview: [nc view]]; //??????????????
window.rootViewController = nc;
[window makeKeyAndVisible];
were window is a UIWindow property of my app delegate and instantiated by the initial nib. I don't know why added [nc view] as a subview to window years ago, but when I commented out that line, all the unbalanced error messages went away. I have not yet tested whether this also works in older iOS yet, but I just wanted to let you know that I no longer have the problem.