In iOS 8, view controllers can now call showDetailViewController:sender:
to have the system determine the proper view controller to present the detail view controller.
In my app, I have a UISplitViewController, which contains two UINavigationControllers in its viewControllers array. The first UINavigationController contains my 'master' view, a subclass of UITableViewController. The second UINavigationController contains my 'detail' view.
Since I'm trying to make this work universally, I'm trying to use showDetailViewController:sender:
to display the detail view:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
[self showDetailViewController:self.itemVC sender:self];
}
This works fine with the Horizontal Compact trait (iPhone style), when self.splitViewController.collapsed == YES
, but not when the trait is Regular (iPad, not collapsed). On the iPad, it replaces the detail UINavigationController with the bare detail view controller (instead of replacing that UINavigationController's viewControllers array).
To get around this, I'm tested for whether or not it's collapsed, and if it isn't, I'm wrapping the detail view controller in another UINavigationController before showing it:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
UIViewController *vcToShow;
// For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it.
if (self.splitViewController.collapsed) {
vcToShow = self.itemVC;
} else {
vcToShow = [[UINavigationController alloc] initWithRootViewController:self.itemVC];
}
[self showDetailViewController:vcToShow sender:self];
}
I suppose alternatively I could just configure self.itemVC
and avoid calling showDetailViewController:sender:
altogether when self.splitViewController.collapsed == NO
:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
// For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it.
if (self.splitViewController.collapsed) {
[self showDetailViewController:vcToShow sender:self];
}
}
But, this feels like it's defeating the purpose of showDetailViewController:sender:
, which is to loosen up the coupling between self
and the rest of the view hierarchy.
Is there a better way to handle this?