iOS- Detect current size classes on viewDidLoad iOS- Detect current size classes on viewDidLoad ios ios

iOS- Detect current size classes on viewDidLoad


As of iOS 8 UIViewController adopts the UITraitEnvironment protocol. This protocol declares a property named traitCollection which is of type UITraitCollection. You can therefor access the traitCollection property simply by using self.traitCollection

UITraitCollection has two properties that you want to access named horizontalSizeClass and verticalSizeClass Accessing these properties return an NSInteger. The enum that defines the returned values is declared in official documentation as follows- (this could potentially be added to in the future!)

typedef NS_ENUM (NSInteger, UIUserInterfaceSizeClass {   UIUserInterfaceSizeClassUnspecified = 0,   UIUserInterfaceSizeClassCompact     = 1,   UIUserInterfaceSizeClassRegular     = 2,};

So you could get the class and use say a switch to determine your code direction. An example could be -

NSInteger horizontalClass = self.traitCollection.horizontalSizeClass;NSInteger verticalCass = self.traitCollection.verticalSizeClass;switch (horizontalClass) {    case UIUserInterfaceSizeClassCompact :        // horizontal is compact class.. do stuff...        break;    case UIUserInterfaceSizeClassRegular :        // horizontal is regular class.. do stuff...        break;    default :        // horizontal is unknown..        break;}// continue similarly for verticalClass etc.


Some useful stuff for Swift 4:

UIViewController Extension to get the classes back as a Tuple.

extension UIViewController {  func sizeClass() -> (UIUserInterfaceSizeClass, UIUserInterfaceSizeClass) {      return (self.traitCollection.horizontalSizeClass, self.traitCollection.verticalSizeClass)  }}

Example Switch statement to consume the function:

    switch self.sizeClass() {    case (UIUserInterfaceSizeClass.unspecified, UIUserInterfaceSizeClass.unspecified):        print("Unknown")    case (UIUserInterfaceSizeClass.unspecified, UIUserInterfaceSizeClass.compact):        print("Unknown width, compact height")    case (UIUserInterfaceSizeClass.unspecified, UIUserInterfaceSizeClass.regular):        print("Unknown width, regular height")    case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.unspecified):        print("Compact width, unknown height")    case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.unspecified):        print("Regular width, unknown height")    case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.compact):        print("Regular width, compact height")    case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.compact):        print("Compact width, compact height")    case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.regular):        print("Regualr width, regular height")    case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.regular):        print("Compact width, regular height")    }

Edit/Addition:

If you are trying to access the trait collection early in the UIViewController's lifecycle they might all be UIUserInterfaceSizeClass.unspecified.

This can be a pain if you happen to do constraints in code.

I recommend access the .traitCollection from the UIScreen shared object.

UIScreen.main.traitCollection

Or even more useful:

UIScreen.main.traitCollection.userInterfaceIdiom


This is nice for testing/debugging:

let sizeClasses = ["Unspecified", "Compact", "Regular"]print("SizeClass w:\(sizeClasses[traitCollection.horizontalSizeClass.rawValue]) h:\(sizeClasses[traitCollection.verticalSizeClass.rawValue])")