Take the 2-minute tour ×

What is the best way to take advantage of the new auto layout features of iOS 6 while still providing compability with older devices on earlier versions of iOS?

share|improve this question
+1. Where you able to figure this out ? Any clue ? –  Janak Nirmal Sep 18 '12 at 7:52
@Jennis Not yet. iOS 6 will officially be released tomorrow (9/19/2012). Hopefully that includes some extra documentation on the subject. –  sglantz Sep 18 '12 at 16:18
I haven't found anything yet. Inquiring minds would like to know! –  Ben Kreeger Sep 20 '12 at 11:59
I do not think that would be possible. Much like storyboards were not possible on iOS4. –  Leo Natan Sep 20 '12 at 21:15
@LeoNatan I am certain that auto layout will not work in iOS 5, but I was hoping there was a relatively graceful way to allow the two methods to coexist. Even if you are starting development on a new app today, it would be hard to go with auto layout. Regardless of the adoption rate for iOS 6 eligible devices, I don't know if developers are ready to turn their backs on the 20+ million first gen iPad, iPhone 3G, and old iPod Touch users. –  sglantz Sep 20 '12 at 23:12

6 Answers 6

up vote 112 down vote accepted

Autolayout can be enabled or disabled on each .storyboard or .xib file. Just select the particular file and modify the "Use Autolayout" property using the File inspector in Xcode:

autolayout property in the File inspector

Using autolayout enabled interface files with the deployment target set to an iOS version prior to 6.0 results in compilation errors, e.g.:

Error in MainStoryboard.storyboard:3: Auto Layout on iOS Versions prior to 6.0

One of your options to use autolayout in a project and still preserve compatibility with iOS4-5 is to create two targets: one for deployment target iOS 6.0 and one for an earlier iOS version, e.g.:

enter image description here

You can create two versions for each of your storyboard and XIB files as well and use the autolayout enabled with the 6.0 target and the other with the legacy target, e.g.:

enter image description here

You then add MainStoryBoardAutoSize to the iOS6 target's Build phases and the other file to the iOS4 target. You can learn more about using multiple targets here.

EDIT: As marchinram's answer points out, if you load you storyboard files from code and do not use the "Main Storyboard" setting in Xcode to set the initial storyboard, you can use a single target.

For me, the cost of the added complexity of maintaining multiple targets and interface files seems to outweigh the benefits of using autolayout. Except for a few special cases, you are probably much better to use plain old auto sizing (or layoutSubViews from code) exclusively if iOS4-5 compatibility is required.

share|improve this answer
Auto layout requires iOS 6 or later. It does not work with iOS 5! Please verify your claims before posting. iOS 5 simply does not have the required APIs (such as the class NSLayoutConstraint). If you don't believe me, check out what other users experience when they try to use Autolayout with iOS 5: stackoverflow.com/questions/11252057/… stackoverflow.com/questions/11198981/… –  Imre Kelényi Nov 23 '12 at 7:43
Yes I think you're right I think I heard it in some wwdc videos, but now I tested it on iOS 5.0 device and it crashed. I will go through these videos and check where did I hear it Nonetheless you're right it does crash on iOS 5.0 –  Asad Khan Nov 23 '12 at 16:45
@ImreKelényi How would you submit this to the app store? I'm not super familiar with the process, but I thought you submit one zipped archive of your .app file. Does having two targets make that process harder at all? Thanks. –  Crystal May 16 '13 at 2:55
@Crystal To be honest, I haven't used this in any app store build and multiple targets might not be a good solution for that at all. Even though you could submit each target as a separate application by using different bundle ids (which has done before for different purposes, e.g. stackoverflow.com/a/8503186/131183), in our case, multiple versions of the same app would appear for the user, which will likely result in rejection. So unless there is a better solution, you should go for using a single target for app store builds (as outlined in stackoverflow.com/a/12592651/131183). –  Imre Kelényi May 16 '13 at 10:08

Do you really need two targets? I got it working like this, I have 2 storyboard like Imre Kelényi said, one with auto layouts enabled and the other without, then in the app delegate i just check which version they are using and select the right storyboard:

#import "AppDelegate.h"

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)

@interface AppDelegate ()
    @property (strong, nonatomic) UIViewController *initialViewController;

@implementation AppDelegate

@synthesize window = _window;

    UIStoryboard *mainStoryboard = nil;
        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS6" bundle:nil];
    } else {
        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS5" bundle:nil];

    self.initialViewController = [mainStoryboard instantiateInitialViewController];
    self.window.rootViewController = self.initialViewController;
    [self.window makeKeyAndVisible];

    return YES;


Having 2 targets works aswell but seems like overkill to me

share|improve this answer
You are right. This works as long as you load storyboards from code and do not use use the target's "Main Storyboard" setting in Xcode. I add a reference to your answer from my post. –  Imre Kelényi Sep 26 '12 at 7:06
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO is overkill. Just test an iOS 6-only class against nil. See developer.apple.com/library/mac/#documentation/developertools/… –  matt Oct 1 '12 at 16:41
Yeah that works too, either way seems ok to me –  marchinram Oct 11 '12 at 21:24
By the time didFinishLaunchingWithOptions: is called state restoration has already occurred, it's better to do all this in willFinishLaunchingWithOptions. Also, storing the initialViewController in a property is unnecessary; using a strong retain is inadvisable. If you need to access the viewController, you can always use the appDelegate's window.rootViewController. –  Elise van Looij Jan 13 '13 at 21:22
yeah good points, wasn't really think about restoration when I answered initially –  marchinram Jan 14 '13 at 21:42

If the layout differences are not large, it's a lot easier to use Springs and Struts to position elements.

share|improve this answer

Inspired by @marchinram's one target idea, this is the solution I finally came up with. Two storyboards, one for struts-and-springs and one for autolayout. In the target summary, I set the autolayout storyboard as the default. Then, in the appDelegate, I check whether I need to load the pre-6.0 struts-and-springs storyboard after all:

    Class cls = NSClassFromString (@"NSLayoutConstraint");
    if (cls == nil) {
        NSString *mainStoryboardName = nil;
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
            mainStoryboardName = @"MainStoryboard_iPad_StrutsAndSprings";
        } else {
            mainStoryboardName = @"MainStoryboard_iPhone_StrutsAndSprings";
        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:mainStoryboardName bundle:nil];

        UIViewController *initialViewController = [mainStoryboard instantiateInitialViewController];
        self.window.rootViewController = initialViewController;
        [self.window makeKeyAndVisible];

Also, I set the deployment target of the struts-and-springs storyboard to iOS 5.1, and that of the autolayout storyboard to Project SDK(iOS 6.0).

I really wanted to do the switch before the default in storyboard is loaded, in willFinishLaunchingWithOptions: but that results in an 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named NSLayoutConstraint' no matter what I tried.

share|improve this answer

Try to use RRAutoLayout: https://github.com/RolandasRazma/RRAutoLayout It's iOS6 AutoLayout backport to iOS5.

share|improve this answer

I've found setting the Xibs main view size to Freeform, and then using Autosizing works a treat. No messing about in code for a view issue.

share|improve this answer

Your Answer


