Enabling auto layout in iOS 6 while remaining backwards compatible with iOS 5 Enabling auto layout in iOS 6 while remaining backwards compatible with iOS 5 ios ios

Enabling auto layout in iOS 6 while remaining backwards compatible with iOS 5


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.


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;@end@implementation AppDelegate@synthesize window = _window;- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    UIStoryboard *mainStoryboard = nil;    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS6" bundle:nil];    } else {        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS5" bundle:nil];    }    self.initialViewController = [mainStoryboard instantiateInitialViewController];    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];    self.window.rootViewController = self.initialViewController;    [self.window makeKeyAndVisible];    return YES;}@end

Having 2 targets works aswell but seems like overkill to me


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