3
votes

In iOS 8, setting the preferredDisplayMode on a UISplitViewController to PrimaryOverlay is generating the following warning:

"Unbalanced calls to begin/end appearance transitions for UINavigationController"

There is no problem if I set preferredDisplayMode to AllVisible or don't set it at all. Problem occurs for all iPads and iPhones in the simulator that I've tried. Problem occurs whether the app starts up in portrait or landscape.

Here's some very simple code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    UITableViewController *tableViewController = [[UITableViewController alloc] init];
    UIViewController *viewController = [[UIViewController alloc] init];

    UINavigationController *masterNavController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
    UINavigationController *detailNavController = [[UINavigationController alloc] initWithRootViewController:viewController];

    UISplitViewController *svc = [[UISplitViewController alloc] init];
    [svc addChildViewController:masterNavController];
    [svc addChildViewController:detailNavController];

    //svc.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
    svc.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

    self.window.rootViewController = svc;
    [self.window makeKeyAndVisible];

    return YES;
}
1
Running into the same issues. I stepped through and the warning seems to be originating in the UIPopoverController...Colin Humber
Creating a UISplitViewController subclass and setting the preferredDisplayMode in viewWillAppear fixes the warning, but then the contentInset of the table view is messed up.Colin Humber

1 Answers

11
votes

Wrap your display code in dispatch_async. Otherwise iOS seems to get confused with other animations running at the same time.

dispatch_async(dispatch_get_main_queue(), ^{
    svc.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
});

or

dispatch_async(dispatch_get_main_queue()) {
    svc.preferredDisplayMode = .PrimaryOverlay
}