Saturday, March 5, 2011

UISplitViewController with details view controller on the left side.


The iPad SDK supports a new type of controller which is called UISplitViewController. This controller has the capability to display the two UIViewControllers (master, detail) so as to take full advantage of the iPad's bigger screen. A typical scenario is the one where you have a UITableViewController(left) and a DetailViewController(right) and the contents of the DetailViewController changes as the user taps on the different rows of the TableViewController. In portrait orientation only the DetailViewController is displayed while the TableViewController is typically displayed as a PopOverController.

While I was working on my SplitView based App that supports Arabic language, I needed the DetailViewController on the Left side instead of the Right in Landscape mode. This turned out to be even easier than I imagined it to be actually and so here is the code and explanation.

First we are going to subclass UISplitViewController

1. Add a new UIViewController to your project and name it "CustomSplitViewController"

2. Open up CustomSplitViewController.h and change it so that it looks something like this:

#import <UIKit/UIKit.h>


@interface CustomSplitViewController : UISplitViewController {


}


@end

-Here we changed the Parent Class from UIViewController to UISplitViewController

3. Save this and open up CustomSplitViewController.m and add the following method to it:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

{

[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];


NSMutableArray *controllers=[NSMutableArray arrayWithArray:self.viewControllers];

UIViewController * first=[[controllers objectAtIndex:0] retain];

UIViewController * second=[[controllers objectAtIndex:1] retain];


[self setViewControllers:[NSArray arrayWithObjects:second,first,nil]];

NSLog(@"%@\n%@",first,second);


[first release];

[second release];

}

-The UISplitViewController when initialized, takes an array of exactly two UIViewController classes and considers The Controller at Index zero as master and Detail Controller at index one. So here we swap the two as the orientation of the device changes. Simple and easy.

4. Once added, your CustomSplitViewController.m should something look like this:

#import "CustomSplitViewController.h"


@implementation CustomSplitViewController


- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

{

[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];


NSMutableArray *controllers=[NSMutableArray arrayWithArray:self.viewControllers];

UIViewController * first=[[controllers objectAtIndex:0] retain];

UIViewController * second=[[controllers objectAtIndex:1] retain];


[self setViewControllers:[NSArray arrayWithObjects:second,first,nil]];

NSLog(@"%@\n%@",first,second);


[first release];

[second release];

}


// Override to allow orientations other than the default portrait orientation.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

// Return YES for supported orientations.

return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation];

}


- (void)didReceiveMemoryWarning {

// Releases the view if it doesn't have a superview.

[super didReceiveMemoryWarning];

// Release any cached data, images, etc. that aren't in use.

}


- (void)viewDidUnload {

[super viewDidUnload];

// Release any retained subviews of the main view.

// e.g. self.myOutlet = nil;

}



- (void)dealloc {

[super dealloc];

}



@end

Now you can use your CustomSplitViewController any way you want to in your project.

0 comments:

Post a Comment