b2cloud

15th November 2012

Forcing UIViewController orientation

Guides | Tutorial By 4 years ago

In an app currently in progress, we need to display a YouTube video to a user. The entire application is fixed in portrait mode, but we wanted to the YouTube video to be forced into landscape whenever opened, and then allow the user to rotate it into portrait or landscape; pretty much the same as the iOS <= 5 YouTube app.

Forcing an interface orientation can be tricky if you don’t know what order things should occur in. This guide will remove the mystery and show exactly how to force it. Firstly, some things have changed from iOS 5 to iOS 6, there are some new orientation methods that need to be overridden (in conjunction with the iOS 5 ones) to make sure your app works on all versions of iOS. Luckily because all we’re doing is overriding methods it doesn’t cause any incompatibilities going backwards on iOS versions :). Secondly, because we’re forcing one to begin with and then allowing rotations, we need to change what’s happening inside the interface rotation methods dynamically (generally you return the same result every single time, well not in this case).

Download the project startpoint. Notice that I’ve selected all orientations except upside down as supported, without this we wouldn’t be able to rotate the phone at all.

I’m not going to use a video controller, but instead just a red view controller for the base (underneath) controller and a green view controller for the one that gets forced landscape.

Run the application, after three seconds the green view controller will present itself over the green. Before it is presented you will notice that the red view controller can be rotated, but this is not what we want. You will also notice the green view controller will always be presented in the same orientation as the phone (even portrait), but we want to always force is landscape.

First we’ll restrict the base controller from rotating. Go into BaseViewController.m and add the following methods, I’ve added comments in explaining each one

- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
	//	(iOS 5)
	//	Only allow rotation to portrait
	return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

- (BOOL)shouldAutorotate
{
	//	(iOS 6)
	//	No auto rotating
	return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
	//	(iOS 6)
	//	Only allow rotation to portrait
	return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
	//	(iOS 6)
	//	Force to portrait
	return UIInterfaceOrientationPortrait;
}

Run the project again, now the red base view controller does not allow rotations, but the green one still comes up in the phones current orientation

Go into ForcedViewController.m. For this we need a boolean that keeps track of whether the view controller is on screen yet or not. When we will appear we set the boolean to NO, and when we have appeared we will set it to YES. This will aid the other method so we know whether or not we can rotate yet. Add the following code to the top (above @implementation)

@interface ForcedViewController ()
{
	BOOL canRotateToAllOrientations;
}

@end

Now add the following inside the implementation

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

	//	We're going onto the screen, disable auto rotations
	canRotateToAllOrientations = NO;
}

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

	//	We're now on the screen, reenable auto rotations
	canRotateToAllOrientations = YES;
}

- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
	//	(iOS 5)
	//	If we can auto rotate then only all orientations except upside down
	if(canRotateToAllOrientations)
		return (toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
	//	Otherwise only allow our forced orienation (see below)
	return (toInterfaceOrientation == self.preferredInterfaceOrientationForPresentation);
}

- (BOOL) shouldAutorotate
{
	//	(iOS 6)
	//	Only auto rotate if we're on the screen (see above)
	return canRotateToAllOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
	//	(iOS 6)
	//	Prefer (force) landscape
	return UIInterfaceOrientationLandscapeRight;
}

That’s it. Run the project and it will work as expected. The project endpoint can be downloaded here.

  • Николай Шубенков

    Thanks a lot! Works fine untill you are not using navigation controller

Recommended Posts

Yammer integrations in ReactJS

Post by 4 years ago

I am writing this blog while I am working on a project for our client’s intranet website. The client requires the website has the ability to share, like and write comments in the website through

Got an idea?

We help entrepreneurs, organizations and established brands from around
the country bring ideas to life. We would love to hear from you!