Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a UITabBarController with a custom UITabBar class without using IB?

Tags:

I can create a UINavigationController with custom bar classes by using initWithNavigationBarClass:toolbarClass:. There doesn't seem to be an equivalent for UITabBarController, so how do I get it to use a custom UITabBar class?

Every solution I've seen so far is unsuitable because either

  1. It uses IB
  2. It adds a second tab bar to the UITabBarController instead of changing its existing one, or
  3. It throws UITabBarController away and makes a new controller class.

I want a real UITabBarController created in code using a custom class for its tab bar. How do I achieve this?

like image 222
Simon Avatar asked Aug 14 '13 09:08

Simon


3 Answers

This is surprisingly hard! The best I've come up with is subclassing UITabBarController and then doing this in the init:

super.init(nibName: nil, bundle: nil)

object_setClass(self.tabBar, CustomTabBar.self)
(self.tabBar as? CustomTabBar)?.setup()

Unfortunately you can't set the class before the call to super.init (not in Swift anyway), and so by the time you change the class the init method has already been run and so won't be called on your custom subclass. To get around this, I've just added a setup() method to do all my customisation in.

Another option in Swift is to extend UITabBar and do something like this:

extension UITabBar {

    open override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        /// Customise in here.
    }

    // Modify the height.
    open override func sizeThatFits(_ size: CGSize) -> CGSize {
        return CGSize(width: size.width, height: 64.0)
    }
}

However this will affect all instances of UITabBar, so I prefer the first option.

like image 114
Luke Rogers Avatar answered Oct 08 '22 18:10

Luke Rogers


This solution from ESTabBarControlller, for replace native UITabBar without IB.

open override func viewDidLoad() {
    super.viewDidLoad()
    let tabBar = { () -> CustomTabBar in 
        let tabBar = CustomTabBar()
        tabBar.delegate = self
        return tabBar
    }()
    self.setValue(tabBar, forKey: "tabBar")
}
like image 37
Ben K. Avatar answered Oct 08 '22 18:10

Ben K.


I do not think it is possible.

Here is the Apple Documentation that talks about the tabBar property of UITabBarController.

You should never attempt to manipulate the UITabBar object itself stored in this property. If you attempt to do so, the tab bar view throws an exception. To configure the items for your tab bar interface, you should instead assign one or more custom view controllers to the viewControllers property. The tab bar collects the needed tab bar items from the view controllers you specify.

The tab bar view provided by this property is only for situations where you want to display an action sheet using the showFromTabBar: method of the UIActionSheet class.

like image 36
Puneet Sharma Avatar answered Oct 08 '22 19:10

Puneet Sharma