How to know iPad is in landscape on orientation change using trait collections?
Trait collections are really helpful to create adaptive interfaces to adjust your apps layout according to the orientation changes. Simply said trait collection will inform you the current device size according to the device orientation.
This is really useful for us because assume you want to change the collection view layout from one column to two column on landscape or change image size according to the orientation.
Apple has given us a handy method to know exactly when the trait collection change so we can catch that event and adjust our layout accordingly.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
}
The problem with trait collection is that in iPad this method will not fire on orientation change because horizontal and vertical size classes are same for landscape and portrait.
https://developer.apple.com/documentation/uikit/uitraitcollection
Luckily we can override trait Collection property to give our own behavior.
Above code I’m overriding the traitCollection property and check the device is iPad and is it in landscape and if both conditions are satisfied, I override the verticalSizeClass property to compact.
* As for ios 13.* we have to add super.traitCollection for UITraitCollection(traitsFrom:) method otherwise the system will complain about unspecified traits.
[Assert] Current fallback trait collection contains one or more unspecified traits: {(
"_UITraitNameDisplayScale",
"_UITraitNameDisplayCornerRadius",
"_UITraitNameSemanticContext",
"_UITraitNameUserInterfaceLevel",
"_UITraitNamePresentationSemanticContext",
"_UITraitNameVibrancy",
"_UITraitNameDisplayGamut",
"_UITraitNameDebugHighlight",
"_UITraitNamePreferredContentSizeCategory",
"_UITraitNameTouchLevel",
"_UITraitNameAccessibilityContrast",
"_UITraitNameLegibilityWeight"
)};
Once you override the property you’ll get the proper behavior for both iPad and iPhone.
One important point to remember is that traitCollectionDidChange method will never fire on app launch for iOS 13.*. This is because UIKit guesses the possible traits for the layout and it will only fire if these guesses are wrong.
Below article will explain this behavior more in details,
https://useyourloaf.com/blog/predicting-size-classes-in-ios-13/
Happy coding!!
Comments
Post a Comment