In my initial view controller, I have have a UITabbarController
as a child view controller.
I want to have UITabbarController
to display its UITabbar
with traitCollection having horizontalSizeClass of Compact so that in the tabbar, image and title appears vertically aligned and not side by side.
Overriding the traitCollection getter of UITabbarController is now not supported in iOS13, Xcode gives below warning.
override var traitCollection: UITraitCollection{
let current = super.traitCollection
let compact = UITraitCollection(horizontalSizeClass: .compact)
return UITraitCollection(traitsFrom: [current, compact])
}
Class MyTabbarController overrides the -traitCollection getter, which is not supported. If you're trying to override traits, you must use the appropriate API.
After researching for appropriate API, I found
open func setOverrideTraitCollection(_ collection: UITraitCollection?, forChild childViewController: UIViewController)
After implementing this I am able to override trait collection of myTabbarController but only after the view has changed orientation. This API is only working if I override viewWillTransition to method.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let currentTC = traitCollection
let compactTC = UITraitCollection(horizontalSizeClass: .compact)
let custom = UITraitCollection(traitsFrom: [currentTC, compactTC])
print("ovverride trait collections before transition")
setOverrideTraitCollection(custom, forChild: tabController)
}
I am only able to override the traits when the device is rotated. This API is not working if I try to override the trait collection in any other view controller lifecycle method. How do I override the traitCollection when the view is initially loaded?
I tried using the same code in the viewDidLoad()
method of my initial view controller but it has no effect.
I'm not sure if the OP ever got this working, but I ran into the same issue recently. In my case, I need to treat the device orientation the same for iPhone and iPad, and in particular set the horizontalSizeClass to .compact in portrait orientation.
Because setOverrideTraitCollection() only works on a child view controller, I had to embed my "master" view controller inside another view controller (which I call my "root" view controller), and handle the trait overrides in the root view controller. As the OP alluded to, this needs to happen at both app startup and whenever the orientation changes. In my case, I could do the startup code in prepareForSegue. Not sure why putting the code in viewDidLoad() didn't work for the OP -- perhaps because he wasn't calling setNeedsLayout() for the child view controller's view.
Here's my root view controller code: