Categories
iOS ObjectiveC Storyboard UIKit Xcode

How to use an Universal Storyboards in Xcode

Welcome to Part 13 of my blog series about iOS game development: Universal Storyboards

At the developer conference WWDC, in June this year, Apple showed a nice concept for targeting multiple form factors: The Universal Storyboards. Basically this replaces the iPad and the iPhone specific storyboards  with one universal storyboard. To enable different layouts for tablet and phone form factors it’s working closely together with Autolayout and Size Classes. I’ll not explain Autolayout and Size Classes deeply in this post. My main motivation was to find out how to convert an old Xcode project with two storyboards into one universal storyboard. If you start a new project, the universal storyboard will be created by default.

As a start project you can use the MyGame project from my earlier posts. You can download it from GitHub: v0.9
This sample needs Xcode 6.
 

Create an universal storyboard:

1. Delete one of the the existing storyboards. In this example the iPad version:
 
 
2. Rename the iPhone Storyboard:
 
 
3. Select the new storyboard as Main Interface for iPhone and iPad:
 
 
 
 
4. Open the storyboard and enable Auto Layout and Size Classes:
 
 
5. Confirm to enable size classes:
 
 
That was easy. Now let’s test it:
 
 
  • iPhone:
 
 
 
  • iPad:
 
 
Hmmmh. We must have missed something.
 
 

Adding Auto Layout Constraints and Size Classes:

We have used the iPhone Storyboard as the new main Storyboard, with a per pixel positioning of the views and UI elements. Therefore it’s not surprising, that the iPad layout looks weird. 
 
Let’s have a look on the view structure. For all elements we have to specify positions and size independent from the form factor or orientation:
 
usb1
 
To address this I’ve added several AutoLayout constraints:
 
usb2
 
 
To model a different layout for iPhone and iPad Size Classes can used. Click at the bottom of the Xcode screen to select a special size class (for example for phone landscape). All new constraints will be limited to the chosen Size Class. Be aware that Size Classes are only working on iOS 8 devices.
 
usb3
 
 
Constraints which are limited to a special Size Class are grayed out. The Size Classes are only working on iOS 8 devices.
 
usb4
 
 
 
 If you need further information here are two excellent articles about Auto Layout and Size Classes:
 

Auto Layout and dynamic view manipulation

 
OK, let’s test it. At a first glance everything looks great, but the parallax effect from the sample project is no longer working. If you think about it, the cause is obvious: I’ve manipulated the size and the behavior of the UI elements in the ViewDidLoad method. After executing this method the Autolayout Constrains are evaluated and the manual changes are overridden.
 
To solve this move the code which manipulates UIViews to the viewDidLayoutSubviews method:
 
Remove from viewDidLoad:
 
[UITools assignBackgroundParallaxBehavior:self.backgroundView];
[UITools assignForegroundParallaxBehavior:self.foregroundViews];
 
Create viewDidLayoutSubviews:
 
-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
 
    [UITools assignBackgroundParallaxBehavior:self.backgroundView];
    [UITools assignForegroundParallaxBehavior:self.foregroundViews];
 
 
}
 
 
The other screens/view controllers of my sample project must be updated the same way.
That’s all for today. You can download the complete code from GitHub v0.10. An updated version to XCode 6.3 can be found here.
 
Cheers,
Stefan