Supporting Different Orientations Within an iOS App

Boon aka Hwee-Boon Yar June 3, 2013
Source

I've seen people asking how to support different device orientations within the same iOS app, especially since iOS 6 introduced some changes to how device orientation is handled and with the growing popularity of RubyMotion (I wrote a RubyMotion tutorial for Objective C developers), there is a new breed of developers. It's really straightforward when the entire app supports the same set of orientation(s). But it gets a little confusing when you want different screens to support different orientations.

Here's some sample code for how to do it correctly in RubyMotion. Developers using Objective C should be able to adapt this too.

In Rakefile (for ObjC developers, do something similar in your info.plist file), set the following to indicate all the orientations supported by the app. If you have a screen in your app that plays video and you want to allow the user to also play it in landscape, you need to include both portrait and landscape orientations here even if the rest of the app is always in portrait.

app.interface_orientations = [:portrait, :landscape_left, :landscape_right]

The rest of it is code. If you use UINavigationControllers anywhere in your app, you will want to use your own subclass instead:

class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) @window.rootViewController = NavigationController.alloc.initWithRootViewController( PortraitViewController.alloc.init) @window.makeKeyAndVisible true end end

The custom UINavigationController just forwards the relevant calls to it's topmost view controller: class NavigationController < UINavigationController #####Orientation

def shouldAutorotate topViewController.shouldAutorotate end

def supportedInterfaceOrientations topViewController.supportedInterfaceOrientations end

def preferredInterfaceOrientationForPresentation topViewController.preferredInterfaceOrientationForPresentation end

def shouldAutorotateToInterfaceOrientation(interfaceOrientation) { topViewController.shouldAutorotateToInterfaceOrientation( interfaceOrientation) end end

Here's how to implement a UIViewController subclass that only supports portrait orientation: class PortraitViewController < UIViewController def initWithNibName(nibName, bundle:nibBundle) super(nibName, nibBundle)

self.view.backgroundColor = UIColor.blueColor
b = UIButton.buttonWithType(UIButtonTypeRoundedRect)
b.frame = [[60, 100], [200, 20]]
b.setTitle('Show VC that rotates', forState:UIControlStateNormal)
b.addTarget(self, action:'click',
    forControlEvents:UIControlEventTouchUpInside)
view.addSubview(b)
self

end

def click vc = PortraitAndLandscapeViewController.new navigationController.pushViewController(vc, animated:true) end

#####Orientation

def shouldAutorotate true end

def supportedInterfaceOrientations UIInterfaceOrientationMaskPortrait end

def shouldAutorotateToInterfaceOrientation(interfaceOrientation) interfaceOrientation == UIInterfaceOrientationPortrait end

#Optional depending on your app def preferredInterfaceOrientationForPresentation UIInterfaceOrientationPortrait end end

Here's how to implement a UIViewController subclass that supports both portrait and landscape orientations: class PortraitAndLandscapeViewController < UIViewController def initWithNibName(nibName, bundle:nibBundle) super(nibName, nibBundle) self.view.backgroundColor = UIColor.greenColor

self

end

#####Orientation

def shouldAutorotate true end

def supportedInterfaceOrientations UIInterfaceOrientationMaskAllButUpsideDown end

def shouldAutorotateToInterfaceOrientation(interfaceOrientation) interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight end

#Optional depending on your app def preferredInterfaceOrientationForPresentation UIInterfaceOrientationPortrait end end

Discussion in the ATmosphere

Loading comments...