Latest 1.0.1
License MIT
Platforms ios 9.0, tvos 9.0

CI Status

How boring is it when you discover on the latest update of your Zeplin’s project that you designer made a TabBar that doesn’t fit in 49px in height?
Or when you discover that they only made an advanced design of TabBar that can’t be a subclass of UITabBar? We all know that moment when you have to imagine a custom hierarchy for your app just for a designer… 😜

TabBarController acts like a UITabBarController that allows you to customize TabBar, transforms and animations.
You can even set a custom anchor for your TabBar. You want a top tabBar? Or just a bottom TabBar on tvOS? Well… you can easily do all these things with exactly 0 line of code, directly from your storyboard (or programmatically, if you’re not a big fan of storyboards 😉)


Xcode 9.0
Swift 4.0


To run the example project, clone the repo, and run pod install from the Example directory first.


TabBarController is available through CocoaPods. To install
it, simply add the following line to your Podfile:

pod 'TabBarController'



You can set up a TabBarController directly from your storyboard, to do it :

  • Add a UIViewController on your storyboard and make it inherits from TabBarController

  • Change the TabBarController’s storyboardSeguesCount attribute

  • Add custom segues that inherit from TabBarSegue
  • For each of your segues you have to set an identifier that starts with ‘tab’ and ends with its index in TabBar

Example: if you want 4 viewControllers in your tab, you have to set storyboardSeguesCount to 4, and name your custom segues tab0, tab1, tab2 and tab3

Et Voila !


let tabBarController = TabBarController(viewControllers: [...])
self.present(tabBarController, animated: true, completion: nil) // present it, set it as rootViewController, what ever..

Hide TabBar

self.hidesBottomBarWhenPushed = true // automatically hide tabBar when pushed, animated: true) // manually hide tabBar, animated or not

See iOS9ViewController.swift example

Scroll To Top

If you want to handle the scroll to top functionallity like system’s UITabBarController when you tap on selected tab in TabBar

func tabBarAction() {
    self.tableView.setContentOffset(.zero, animated: true)

See iOS9TableViewController.swift example


TabBarController provide extensions for UIViewController: // return the tabBarController of self // return the tabBar of // return the tabBarItem of self's parent in TabBarController /* In case of the root view controller of your controller's tab is a UINavigationController, TabBarController add it in private parent controller. 
Using on this private parent controller (via for example) return your navigationController*/ // return true if != nil


TabBarController allows you to use UINavigationController as root view controller of each tab of your tabBarController,
But to do so, it add it in a private parent controller and set its delegate to the TabBarController
If you want to use custom delegate for your UINavigationController please redirect thoses events to the tabBarController, otherwise hidesBottomBarWhenPushed and other displays functionalities will not work.

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
    //, willShow: viewController, animated: animated)

func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
    //, didShow: viewController, animated: animated)


Create a UIView class and make it inherits from TabBarProtocol

import TabBarController

class YourTabBar: UIView, TabBarProtocol {

    weak var delegate: TabBarDelegate?

    func setItems(_ items: [UITabBarItem]?, animated: Bool) {
        // Update view

    func setSelectedItem(_ item: UITabBarItem?, animated: Bool) {
        // Update view

See SpringboardTabBar.swift example


Link the tabBar outlet from your TabBarController to your custom tabBar in storyboard


let tabBar = YourTabBar()
let tabBarController = TabBarController(viewControllers: [...], tabBar: tabBar)

Advanced Customization


TabBarController supports four anchors for TabBar:

  • top: tvOS style
  • bottom: iOS style
  • left
  • right


Set the tabBarAnchorIndex attribute of your TabBarController (0: top, 1: bottom, 2: left, 3: right)


let tabBar = YourTabBar()
let anchor: TabBarAnchor = .top
let tabBarController = TabBarController(viewControllers: [...], tabBar: tabBar, anchor: anchor)


class YourTabBar: UIView, TabBarProtocol {

    var additionalInset: CGFloat { return 0 } // positive or negative value

    func setAnchor(_ anchor: TabBarAnchor) {
        // Update view

    func setTabBarHidden(_ hidden: Bool) {
        // Update view


TabBarProtocol provides optionnal method that allows you to customize animations and frames for your TabBar.

class YourTabBar: UIView, TabBarProtocol {

    func animator() -> TabBarAnimator? {
        return YourTabBarAnimator()

class YourTabBarAnimator: TabBarAnimator {

    func tabBarInsets(withContext context: TabBarAnimatorContext) -> UIEdgeInsets {
        // return additional insets below your TabBar

    func animateTabBar(using context: TabBarAnimatorContext) {
        // Animate and update frame of the TabBar
        UIView.animate(duration: 0.3, animations: {
            context.tabBar.frame = finalFrame // update frame
            context.animate() // animate insets updates
        }, completion: context.completeTransition) // call completeTransition

See TabBarAnimator.swift


If you want to use custom animations on your TabBarController you have to make it inherits from TabBarControllerDelegate

extension YourTabBarController: TabBarControllerDelegate {

    func tabBarController(_ tabBarController: TabBarController, animationControllerFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        // return your custom UIViewControllerAnimatedTransitioning

See SpringboardTabBarController.swift example

Prior iOS 11 support

TabBarController is optimized for iOS 11 and safeArea, if you want support iOS 9 & 10 you need to use additional insets.
This library provides different ways to do so.

TabBar Top/Bottom Inset Constraint

The TabBarChildControllerProtocol provides two optional properties that allows you to manage TabBar insets easily :

var tabBarTopInsetConstraint: NSLayoutConstraint!
var tabBarBottomInsetConstraint: NSLayoutConstraint!
var tabBarLeadingInsetConstraint: NSLayoutConstraint!
var tabBarTrailingInsetConstraint: NSLayoutConstraint!

Since UIViewController inherits from TabBarChildControllerProtocol, just add these properties in your class (use IBOutlet if you want to use them Interface Builder)

See iOS9ViewController.swift example

Update TabBar Insets

If you want to add insets on your UIScrollView instead of directly update its frame, you can handle it using this method:

func updateTabBarInsets(_ insets: UIEdgeInsets) {
    self.tableView.contentInset.bottom = insets.bottom
    self.tableView.scrollIndicatorInsets.bottom = insets.bottom

See iOS9TableViewController.swift example


Arnaud Dorgans, [email protected]


TabBarController is available under the MIT license. See the LICENSE file for more info.

Latest podspec

    "name": "TabBarController",
    "version": "1.0.1",
    "summary": "TabBarController acts like a UITabBarController that allows you to customize TabBar, transforms and animations.",
    "description": "TabBarController acts like a UITabBarController for iOS and tvOS, that allows you to customize TabBar, transforms and animations.",
    "homepage": "",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    "authors": {
        "Arnoymous": "[email protected]"
    "source": {
        "git": "",
        "tag": "1.0.1"
    "social_media_url": "",
    "platforms": {
        "ios": "9.0",
        "tvos": "9.0"
    "source_files": "TabBarController/Classes/**/*",
    "swift_version": "4.0"

Pin It on Pinterest

Share This