Search code examples
iosswiftuikituitabbarcontrolleruitabbar

Custom UITabBar subclass without Interface Builder


Using IB (be it with a Storyboard or a XIB), one can easily have the UITabBarController use a subclass of UITabBar, by editing the class name in the Identity Inspector -> Custom Class.

How to mimic this "custom class" feature of IB, without using it at all ?

I tried the following (in my subclass of UITabBarController) :

var customTabBar = MyCustomTabBarSubclass()

override var tabBar: UITabBar {
    return customTabBar
}

To no avail – the tab bar is displayed, but blank. The issue is not elsewhere since returning super.tabBar from the overriden var fixes it.

The issue, I guess, is that I'm not setting up my customTabBar (frame, position, adding it to the view hierarchy), but I'd like to have the UITabBarController loadView (I think that's the one, not sure) do it for me, the same way it sets up any other UITabBar.

Ideas ?


Solution

  • I think you can't. For this question, I had some time to scan through the documentations of UITabBar and UITabBarController.

    The tabBar property of UITabBarController is a get-only.

    @available(iOS 3.0, *)
        open var tabBar: UITabBar { get } // Provided for -[UIActionSheet showFromTabBar:]. Attempting to modify the contents of the tab bar directly will throw an exception.
    

    Furthermore, it is stated in UITabBarController's documentation that you shouldn't manipulate such property.

    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 show(from:) method of the UIActionSheet class.

    Just wanna add: but unlike this UITabBarController, subclassing the UINavigationController gives you the power to init such subclass with a subclass of UINavigationBar:

    UINavigationController(navigationBarClass: <#T##AnyClass?#>, toolbarClass: <#T##AnyClass?#>)
    

    Unfortunately, UITabBarController does not have such kind of init method.