Create a Tabbar Controller with a Master-Detail Template

Create a TabBar Controller with a Master-detail template?

You should embed the navigation controller (of either the master or detail VC) in a tab bar controller, then delete the connection between the split view controller and that navigation controller. Finally, remake the connection from the split view controller to the tab bar controller. You'll also need to make several code changes, because the template code refers to the detail controller by its hierarchy in the split view controller, which will now be different.

add a new tab containing a master-detail in iOS

You can do it like this... (Adding example to Phillip's answer)

MasterViewController *masterViewController=[[MasterViewController alloc] init];
UINavigationController *navigationController=[[UINavigationController alloc] initWithRootViewController:masterViewController];
[masterViewController release]; //if not ARC

tabbarController.viewControllers=[NSArray arrayWithObjects:navigationController,
viewController1,
viewController2,
//More view controller objects,
nil];
[navigationController release]; //if not ARC

MasterViewController may contain a UITableView as subview or it may simply be a UITableViewCotroller (as you need Master-Detail flow.).

Xcode Master-Detail Template adding UITabBarController as the Master of the UISplitViewController

I'm still open to other answers as there are a few ways to solve this, but one way that worked is by modifying the Master-Detail App Template's splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: implementation.

First some explanation; the implementation of splitViewController:showDetailViewController:sender: in the last part of the question above solved one (significant) problem on the UI side. It allowed the detail view to be pushed onto the master UINavigationController's stack while keeping the master UITabBarController visible and allowing navigation back to the master view. It did this in collapsed mode by taking the DetailViewController out of the split view controller's detail navigation controller and pushing the DetailViewController onto the stack. This is different from the default Master-Detail template as, in that version, the detail navigation controller is pushed over the master navigation controller and still works (I just haven't been able to find a way to make it work like this after adding the UITabBarController). Having done this, when we rotate to the landscape (expanded) view, everything still works correctly (the detail navigation controller comes back), but when we rotate to the portrait (collapsed) view, we end up back at the master view even when a detail item is selected.

I forced the push of the detail view (if there was data to display) by adding an additional condition to splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: by triggering a segue to the detail view from the master:

if ([secondaryViewController isKindOfClass:[DetailViewController class]] && [(DetailViewController *)secondaryViewController detailItem] != nil && [primaryViewController isKindOfClass:[UITabBarController class]])
{
UINavigationController * currentMasterNavigationController = ((UITabBarController *)primaryViewController).selectedViewController;
MasterViewController * masterViewController = (MasterViewController *)[currentMasterNavigationController visibleViewController];
[masterViewController performSegueWithIdentifier:@"showDetail" sender:masterViewController];
return YES;
}

The modified function in full is:

- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController
{
if ([secondaryViewController isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]] && ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil))
{
// Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
return YES;
}
else if ([secondaryViewController isKindOfClass:[DetailViewController class]] && [(DetailViewController *)secondaryViewController detailItem] != nil && [primaryViewController isKindOfClass:[UITabBarController class]])
{
UINavigationController * currentMasterNavigationController = ((UITabBarController *)primaryViewController).selectedViewController;
MasterViewController * masterViewController = (MasterViewController *)[currentMasterNavigationController visibleViewController];
[masterViewController performSegueWithIdentifier:@"showDetail" sender:masterViewController];
return YES;
}
return NO;
}

This does still seem too much of a hack to me, but it does work. I'd love to see an answer that is cleaner than this, which works more like the default template while still allowing for the UITabBarController



Related Topics



Leave a reply



Submit