Ios – how can I use one storyboard for 4″ and 3.5″ iphone screens with autolayout (ios6 + ios7)

autolayoutinterface-builderiosiphonenslayoutconstraint

While there are many questions and answers about building a storyboard layout that would work both on 4" and 3.5" screen sizes, I couldn't find a suitable solution for the following scenario.

I use autolayout with ios6 (and ios7), and I don't have to support landscpae or ipad. I have a UIView with several subviews, which have to look as the mockup below.
It is easy to set up autolayout constraints in the storyboard to fit either of the screen sizes. My question is – how do I make autolayout choose the correct constraints depending on the screen size at runtime?

SCREEN MOCKUPS

Note, that I DONT want to use 2 different storyboards. Doing so across my whole application would be a lot of work, and I would have to hook up all the delegates, outlets and actions on each storyboard. A change in a screen would require me to do double the work.

I have tried 2 methods to make this work on one storyboard, but I'm not satisfied with either of them.

  • Double the constraints. The larger constraint (50) has a higher priority than the lower constraint (30). The problem with this approach is that on the 3.5" screen size, autolayout may pick a just few lower priority constraints – enough to satisfy the layout – but leave some high priority constraints.

double constraints

  • Subclass NSLayoutConstraint. In this method, all the constraints in the storyboard are set to be NSDualLayoutConstraint. In in initialization code of NSDualLayoutConstraint, the constant of the constraint is changed to the value of 3_5_constant in case the runtime screen size is 3.5". this method is more deterministic, but you can't see the 3.5" layout in the interface builder preview.

enter image description here


If only interface builder constraints had a secondary constant value that would be applied when the screen size is 3.5", it would solve my problem..
So I remain with my question – how can I properly use a single storyboard to layout its subviews correctly for 4" AND 3.5" screen sizes?

Best Answer

If you want to use only one storyboard and you do not want to utilize auto layout, which would make your life a lot easier for what you've shown in your diagram, you will have to layout your views in code.

You will just need to detect if the user is running on a 4" device and layout your views accordingly.

#define IS_568_SCREEN (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)

if (IS_568_SCREEN) {
    // Lots of code to layout for 4" devices
} else {
    // Lots of code to layout for 3.5" devices
}

However, if you were to use autolayout for this, you'd find it's going to save you a ton of time and code. Instead of having to manually layout every view in code using the solution I mentioned above, you'd simply need to update the y and height constraints depending on the device.

Considering this diagram showing what autolayout would handle for you and what you'd need to update manually, this should help paint a better picture of just how much you'll save with utilizing autolayout.

enter image description here

#define IS_568_SCREEN (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)

if (IS_568_SCREEN) {
    self.layoutConstraintY.constant = 50.0f;
    self.layoutConstraintHeight.constant = 248.0f;
} else {
    self.layoutConstraintY.constant = 30.0f;
    self.layoutConstraintHeight.constant = 220.0f;
}
[self layoutIfNeeded];