Size classes iPad Portrait/Landscape

Apple introduced the concept of adaptive user interfaces in iOS 8 relying on a combination of Auto Layout and Size Classes. An adaptive interface is one that makes the best use of the available space. The two main components of the adaptive model on iOS are Auto Layout and Traits.

A UITraitCollection object describes the properties, or traits, of a user interface element. These traits define a display scale, the user interface idiom (an iPhone or iPad), and most importantly a vertical and a horizontal size class.

Trait collection object has two size classes: horizontal and vertical. Each of these classes has three possible values: compact, regular or any. These values can change based on the device and its orientation. Every view or auto-layout constraint can exist in one or several other size classes.

Size class traits make possible to support multiple devices and orientations. They also enable the condensing of universal apps into one storyboard file. Developers are encouraged to work with generic layouts, and only use device-specific Size Classes when necessary.

The current Size Classes rules may create some problems for Designers/Developers that want to differentiate iPad UI design based on orientation but want to maintain the advantage of the Size Classes use.

Size classes don’t cover the difference between iPad Portrait and Landscape: they both have Regular Width and Regular Height.

The trick is to override the trait collection in the ViewController: for example to return a custom horizontalSizeClass for iPad Portrait

The code below return a Compact Width and Regular Height for iPad in Portrait; so basically this is going to have the same behaviour of the iPhone in Portrait.

public class CustomTraitCollectionViewController: UIViewController {
override public var traitCollection: UITraitCollection {
if UIDevice.currentDevice().userInterfaceIdiom == .Pad && UIDevice.currentDevice().orientation.isPortrait.boolValue {
return UITraitCollection(traitsFromCollections:[UITraitCollection(horizontalSizeClass: .Compact), UITraitCollection(verticalSizeClass: .Regular)])
}
return super.traitCollection
}
}

You can customise this code to have different custom behaviours for different device+orientation when using Size Classes.

If you override UITraitCollection for the main class Window you can have the same custom behaviour in all the App.