The Ask: I want to have different layouts between Portrait vs Landscape on the iPad. (I'm successful on the iPhone But iPad share similar size classes)
What I've done/Tried:
Reading and searching thru Google and SO, I haven't found the solution. What I did learn was about overriding UITraitsCollection
and If possible, I would like to force the iPad Landscape configuration to follow the same one which I've already set up for the iPhone Landscape mode using hCompact
I tried this solution https://stackoverflow.com/a/60409218/14414215 but unsure where to put it and when just placed within the UIViewController
, when running, the app doesn't even call it. (It's likely cos I don't have my views within a childViewController?)
This post here also references UITraitsCollection
https://stackoverflow.com/a/41374705/14414215 however there is a lack of an example.
I'm fairly sure that this is something that many apps are doing but I'm not able to find the solution.
For reference: This is what I want to achieve on the iPad as well. (iPhone works great using this solution from @DonMag)
StackView layout side by side & on Top of each other (like zStack)
With different device screen aspect ratios, and the multi-tasking capabilities on iPads, you're encouraged to think in terms of size not orientation.
If your app is being run with Slide Over / Split View, the size class can be wC hR
even when the device is in "landscape orientation."
If you want to change layout based on aspect ratio:
You may want to create your own constraint collections and activate / deactivate them in viewWillTransition(to size:...)
If you want to stick with Trait variations, you'll run into problems trying to manipulate them for the "root" view of a controller.
You could try making your controller a child view controller, either by embedding it in a UIContainerView
or adding it via code, and then implementing (in the "parent" view controller):
class ParentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let vc = storyboard?.instantiateViewController(withIdentifier: "myVC") as? MyRealViewController {
addChild(vc)
view.addSubview(vc.view)
vc.didMove(toParent: self)
}
}
override func overrideTraitCollection(forChild childViewController: UIViewController) -> UITraitCollection? {
if childViewController.view.bounds.width > childViewController.view.bounds.height {
let collections = [UITraitCollection(horizontalSizeClass: .regular),
UITraitCollection(verticalSizeClass: .compact)]
return UITraitCollection(traitsFrom: collections)
}
return super.overrideTraitCollection(forChild: childViewController)
}
}