I have a view controller that contains a table view, the items in the table can be selected and a detail view controller duly created.
The items in the table represent items that can have a time based trigger associated with them and a local notification is scheduled for each item, if the app is in the foreground when a local notification expires then the detail view for the item is automatically displayed.
I have a problem that manifests when two notifications expire at the same time which results in the views not being displayed properly and in addition the console logs: "Unbalanced calls to begin/end appearance transitions for NNN" where NNN is my detail view controller.
The table view controller is created as follows:
self.tableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.tableViewController];
self.window.rootViewController = navController;
When a local notification expires and didReceiveLocalNotification: is invoked the app broadcasts a notification using NSNotifcationCenter postNotificationName: and to which the table view controller is listening for. When the table view controller receives that notification it creates the detail view controller and pushes it to the stack as:
[self.navigationController pushViewController:detailViewController animated:YES];
I read somewhere that there could be a problem if a view controller pushes another view controller when it itself is not on the top of the stack - so I thought this must be the problem, because when the table view controller receives the 2nd notification it will no longer be on the top of the navigation stack because it will have previously just pushed a detail view controller onto the stack when the first notification arrived.
So I changed the push code to this:
[[self.navigationController topViewController].navigationController pushViewController:detailController animated:YES];
But it made no difference.
So I next thought there could be a problem because the first detail view controller was not getting the chance to fully display before the 2nd view controller was pushed - so I changed my app's notification posting from using:
[[NSNotificationCenter defaultCenter] postNotificationName:
to
[[NSNotificationQueue defaultQueue] enqueueNotification: postingStyle:NSPostWhenIdle]
So that the pushes wouldn't occur within the same iteraction of the app loop. But that made no difference, nor did attempting to introduce a delay to the pushing of the detail view controlle:
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[[self.navigationController topViewController].navigationController pushViewController:detailController animated:YES];
});
I've no idea what the problem is or what to try next, any ideas?