Orientation Support in iOS 6

In iOS apps specially iPad apps orientation really plays a great role. Sometimes we stick to just one type of orientation but if we handle all types of orientations that will give our app a more versatile look.

Basically there are two types of orientations that are supported in Xcode –

1. UIDeviceOrientation

2.UIInterfaceOrientation

UIDeviceOrientation

First we talk about UIDeviceOrientation.There are six types of device orientations supported in Xcode.

1.UIDeviceOrientationFaceDown
2.UIDeviceOrientationFaceUp

both these orientations work corresponding to position of Home button of Device whether it is faced up or down.

3.UIDeviceOrientationLandscapeLeft
4.UIDeviceOrientationLandscapeRight

both of the above orientations work on Landscape mode depending on left or right position.

5.UIDeviceOrientationPortrait
6.UIDeviceOrientationPortraitUpsideDown

both of the above orientations work on Portrait mode depending on position of Home Button.Normal way of handling device is portrait but if we rotate device by 180 degree portraitUpsodeDown will be current orientation.

Normally we don’t need Device orientations because Face Up and Face Down are very rear cases to be handle.

UIInterfaceOrientation

Next comes UIInterfaceOrientation. There are four types of UIInterfaceOrientation –
1.UIInterfaceOrientationPortrait
2.UIInterfaceOrientationPortraitUpsideDown
3.UIInterfaceOrientationLandscapeLeft
4.UIInterfaceOrientationLandscapeRight

These are simple interface orientations that we normally face when we rotate device by 90 degrees or 180 degrees.

Prior to iOS 6 versions

– (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
method was used to handle orientations.This method was called when we change orientation,we have to return Bool value whether it should rotate or not.But in iOS6 this method is deprecated.
Because View controllers (such asUINavigationController) do not consult their children to determine whether they should autorotate.
So new method is introduced in iOS 6
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration

This method is called automatically when we change interface orientation of device. So next comes what to do when this method is called. There are two approaches to handle this. First is make two separate views one for portrait and one for landscape,then handle their show and hide. An example is shown below –

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)

self.viewPortrait.hidden=NO;
self.viewLandscape.hidden=YES;

else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation==UIInterfaceOrientationLandscapeRight)

self.viewPortrait.hidden=YES;
self.viewLandscape.hidden=NO;
}

But this approach is not recommended because same outlet will be connected twice which can cause conflicts on Running the code.Another approach is to load different nib file on change of orientation.
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)

[[NSBundle mainBundle] loadNibNamed:@”RootViewController”
owner:self
options:nil];
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation==UIInterfaceOrientationLandscapeRight)

[[NSBundle mainBundle] loadNibNamed:@”RootViewLandscape”
owner:self
options:nil];
}

This method is called only when we change orientation in a particular view.When we want to push into another nib then we should load current orientation specific nib.This can be checked before pushing the viewController.For example

CollectionViewController *collectionVC;

if (isPortrait)
collectionVC = [[CollectionViewController alloc] initWithNibName:@”CollectionViewController”
bundle:nil];
else
collectionVC = [[CollectionViewController alloc] initWithNibName:@”CollectionViewLandscape”
bundle:nil];

collectionVC.currentCollectionType = Videos;

[self.navigationController pushViewController:collectionVC
animated:YES];

where isPortrait’s value is set in prefix.pch file as shown below

#define isPortrait UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])

But this could be conflicting as when we pop from that viewController then again we again have to load current orientation specific nib. To overcome this we can manually call willRotateToInterfaceOrientation method in viewWillAppear. For example –

-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];

[self willRotateToInterfaceOrientation:self.interfaceOrientation
duration:.2];
}

Now you don’t need to check orientation before pushing to next ViewController because everything is being controlled in viewWillAppear of every ViewController class.

Leave a Reply

Your email address will not be published. Required fields are marked *


+ nine = 14

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>