Search code examples
iosswiftuitabbarcontrolleruitabbar

Running tabBarItem code before view controller loads


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:

initial result - only the first tab bar item is in the correct position

If you tap on the second item, the second view controller loads and it changes position as well.

second tab bar item in the correct position

I need to load this code for each tab bar item, so it looks like this from the start:

desired result


Solution

  • 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) }
        }
    }