UISplitViewController, MultipleDetailViews with Navigation Controller
this tutorial shows how to have navigation controller in both master view and detail view of UISplitViewController.
Created new project with splitview template in Xcode.
Now first remove splitviewcontroller in mainwindow.nib,since we are creating split view controller programmatically .now in your appDelegate method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after app launch. self.splitViewController =[[UISplitViewController alloc]init]; self.rootViewController=[[RootViewController alloc]init]; self.detailViewController=[[FirstDetailViewController alloc]init]; UINavigationController *rootNav=[[UINavigationController alloc]initWithRootViewController:rootViewController]; UINavigationController *detailNav=[[UINavigationController alloc]initWithRootViewController:detailViewController]; self.splitViewController.viewControllers=[NSArray arrayWithObjects:rootNav,detailNav,nil]; self.splitViewController.delegate=self.detailViewController; // Add the split view controller's view to the window and display. [window addSubview:self.splitViewController.view]; [window makeKeyAndVisible]; return YES; } |
this will make master and detail of splitview as navigation controller.
Make two detail view controller first and second.
the main code for replacing detail navigation stack with view controller is
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { /* When a row is selected, set the detail view controller's detail item to the item associated with the selected row. */ NSUInteger row = indexPath.row; [self.appDelegate.splitViewController viewWillDisappear:YES]; NSMutableArray *viewControllerArray=[[NSMutableArray alloc] initWithArray:[[self.appDelegate.splitViewController.viewControllers objectAtIndex:1] viewControllers]]; [viewControllerArray removeLastObject]; if (row == 0) { self.firstDetailViewController=[[[FirstDetailViewController alloc] init]autorelease]; [viewControllerArray addObject:self.firstDetailViewController]; self.appDelegate.splitViewController.delegate = self.firstDetailViewController; } if (row == 1) { self.secondDetailViewController=[[[SecondDetailViewController alloc]init]autorelease]; [viewControllerArray addObject:self.secondDetailViewController]; self.appDelegate.splitViewController.delegate = self.secondDetailViewController; } [[self.appDelegate.splitViewController.viewControllers objectAtIndex:1] setViewControllers:viewControllerArray animated:NO]; [self.appDelegate.splitViewController viewWillAppear:YES]; [viewControllerArray release]; } |
done You can download the code below
so now you have both of your view controller of UISplitViewController with navigation controller
MultipleDetailViewsWithNavigator
Categories: iPad, Objective-C

Hello Kshitiz Ghimire, The link to the sample code appears to be broken.
Can you fix it ?
Thanks for the tutorial.
done , thank you for letting me know
hello kshitiz ..this is an amazing post. but in this once i selected a view from a popovercontroller, the root button disappears and we will not go back to another view . do u know how to fix it?
Fixed now
Hey!
I get an runtime error in the below method, because toolbar is not exist.
- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
NSMutableArray *items = [[self.toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[self.toolbar setItems:items animated:YES];
[items release];
self.popoverController = nil;
}
actually the function is in DetailViewController.m
Great Post. Thank you my friend. You saved my day.
Hello
thx for this post!
I am a newbi and so i have a question
what is this code snippet in the file FirstDetailViewController.m on top doing? is it a composition? but of what… i do not understand and way you do not the same in the SecondDetailViewController.m
@interface FirstDetailViewController ()
@property (nonatomic, retain) UIPopoverController *popoverController;
@end
thx you
hi it is same thing as second detailviewcontroller , just a different way. you can follow any way. actually when you you use default template from code it does in that way , but it is your choice
Hello
Thx for this post!.I faced one problem,When i click inside Popover it does not close popover.
[popoverController dismissPopoverAnimated:YES];
delegate not working properly.Can you help me this problem
Hello Kshitiz Ghimire,
When i click inside Popover it does not close popover.
[popoverController dismissPopoverAnimated:YES];
delegate not working properly.Can you help me this problem.
Please provide any steps .
Can you update from your end
Does anyone solved the problem of dismissing the popover?
Thank
This approach works very well, thanks! Unfortunately, I too am unable to figure out how to dismiss the popover. I understand that I must keep a reference to the popover somewhere so that I can send it the dismiss message.
What I can’t figure out is where/how to create and store the reference to the popover controller when used with this approach. Where is the popover actually initialized: appDelegate, rootViewController, or in the detail view controllers? As noted above, sending dismiss to the property of the detail views does not seem to work.
Ok, figured it out. Well… found a way that works, can’t say that it’s best.
The problem with the sample as it stands is that nothing actually sets the popoverController property of the detail view to point to the actual popover controller. So, you can call dissmiss on this all day long and nothing will happen; its nil.
The example implements two methods of the splitviewcontrollerdelegate protocol in each detail view controller. The trick is to implement the third method of this protocol, “willPresentViewController”. This method is called whenever the popover is displayed. Inside your implementation of this method, set the popoverController property of your class to the “pc” that gets passed to this method. Now your property actually contains a pointer to the real popover controller.
Back in whatever part of your code that will switch a detail view, before you switch the view, grab the value of the current detail view’s popoverController property.
[[[[self.splitViewController.viewControllers objectAtIndex:1] viewControllers] objectAtIndex:0] popoverController];
This points to the active pc, so you can actually send the dismiss message to it. I can’t claim that any of this is elegant or “best practice” but its working for me.
im new to the uisplitviewcontroller concept so please bare with my ignorance.
i’m struggling to understand the relationship/hierarchy of the different controllers when using the splitviewcontroller (ie. relationship between the splitview, rootview, detailview, navcontroller…)
i GET that the splitviewcontroller holds two viewcontrollers: one for the navigation controller (for rootview) and another for the detailview controller. but what i need is a bit more complex…
given a list of options (rootviewcontroller), how would i add a uinavcontroller for each option? so every option has it’s own stack of detail views
here’s what i need
ROOTVIEW
|— OPTION 1
|— (uinavigationcontroller)
| |OPT1_DETAILVIEW
| |– OPT1_DRILLDOWNVIEW1
| |–OPT1_DRILLDOWNVIEW2
| |–etc
|— OPTION 2
|— (uinavigationcontroller)
| |OPT2_DETAILVIEW
| |– OPT2_DRILLDOWNVIEW1
| |–etc
|— OPTION 3, etc
CAN SOMEONE HELP ME PLEASE!!!!
PS: i’ve looked at NUMEROUS examples and none of them cater for my requirement [or I'm dumb]! FYI -neither apple’s multipleview sample nor MGSplitview helped
Does anyone solved the problem of dismissing the popover?
I use this project for my first project.
Please help me.
Thank you very much.
How to dismiss the popover?
This answer was very helpful. thanks !!
This is nice. However, the rotations are not animated. It seems like the rotations are completed almost immediately and only the status bar rotation gets animated. Is there any way to match the rotation speed and duration of the status bar?
Sorry about my last comment. It’s not happening anymore…
Hi
For an universal iOS app (iPad and iPhone) Is it possible to make the iPad version the only device to support auto-rotate?
the iPhone will NOT support auto rotate.
is this possible or not?
ya thats possible, just detect the device and return supported interface orientation in shouldautorotate method in view controller
HEllooo Frndz……!!!
I have to use UISplitViewController.and i want to add UISplitViewController to UINavigationController. bt i can’t do this..and display message in Consol..”Application tried to push a nil view controller on target .”…….so PLZ…give me answer for how to add UINavigationController to UISplitViewController…Thanx Friend…:)
Hi…
Now I have this problem since a week ago and until now I understand how it is handling. thank you very much indeed for your contribution, you saved my life, not only me but several of us. Greetings from Mexico.
hi i followed your tutorial and try to implement my own stuff like in one of the second detailview i have a button when i click on it it should push to new view controller but with the same row selected .it does but when i select another row there i am getting naviagtion button which leads to second view . why it is coming like that please help me i am looking for solution for many days
Hello !
Fantastic work !
This is exactly what I needed.
But could you give me a hint, if you’re patient enough, Could you tell me what is the simplest way to push a new view controller in the detail view ?
I tried different ways in the RootViewController.m, but I think I got it wrong.
I know this question must seem dumb to you, but I’m a beginner at iOS programming.
It would be so nice of you to answer this question.
Alex.
To be as clear as possible, let’s say I want to put a button on the first view controller that will trigger the action of pushing another view in the detail view.
To be honest, I’m trying to push some view controllers (forms for the user) in the detail view.
Greetings from France.
Hi.
I have a problem with Popover window on 5.1 simulator. Normal typical popover window is displaying properly for 4.3 & 5.0 Simulator, But 5.1 Simulator at portrait mode displaying just like splitwindow…
…
if any one solved this problem ps tell…….
Great example. It is what I need. Just I have one question. I’ve read a lot about delegates, because I can’t completely understand that concept. What I read, is “delegates” are methods declared inside a protocol. The class that declares that “delegate” need to implement that methods. In this example. you don’t declare any protocol, but declare references to your AppDelegate in every ViewController. Is this because in you AppDelegate are declared the SplitViewController?
Thanks