Thursday, September 18, 2014

How to use an Universal Storyboard in Xcode

Welcome to Part 13 of my blog series about iOS game development.

At the developer conference WWDC, in June this year, Apple showed a nice concept for targeting multiple form factors: The Universal Storyboard. 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:


To address this I've added several AutoLayout constraints:



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.



Constraints which are limited to a special Size Class are grayed out. The Size Classes are only working on iOS 8 devices.




 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.

Cheers,
Stefan

2 comments:

  1. my xcode freezes when i enable class sizes. do you have any idea why does that happen?

    ReplyDelete
  2. Not really. Does it freeze with my sample code? I've created this post with a Xcode 6 beta version. Unfortunately it seems that the final version of Xcode contains more bug the the beta version.

    ReplyDelete