I have a tabbar app, and I put the following code in my view controllers:
let orientation = UIDevice.current.orientation
if orientation == .portrait {
self.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -17.0)
} else if orientation == .landscapeLeft || orientation == .landscapeRight {
self.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 0.0) // updating the title positon
}
This changes the offsets for my tab bar items' titles. In landscape, the offsets get reversed automatically, so I have to do it manually. This works, but only when you actually click on a tab bar item and it loads a view controller.
I want to load this code at the start, so it changes the offset when you launch the app (before the view controllers load). Here are some pictures to describe what I said:
When you first launch the app, this is the first view controller, so it loads that code and it changes position:
If you tap on the second item, the second view controller loads and it changes position as well.
I need to load this code for each tab bar item, so it looks like this from the start:
You should subclass UITabBarController
and execute the code that changes the title position adjustment after the controller loads (viewDidLoad
) and every time the view size/orientation changes (viewWillTransition
).
class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
tabBarItemsUI()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { [weak self] context in
self?.tabBarItemsUI()
})
}
fileprivate func tabBarItemsUI() {
let isLandscape = [.landscapeLeft, .landscapeRight].contains(UIDevice.current.orientation)
tabBar.items?.forEach { $0.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: isLandscape ? 0 : -17) }
}
}