Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extension on UITabBarController for hiding/showing the tab bar.
extension UITabBarController {
/**
Show or hide the tab bar.
- Parameter hidden: `true` if the bar should be hidden.
- Parameter animated: `true` if the action should be animated.
- Parameter transitionCoordinator: An optional `UIViewControllerTransitionCoordinator` to perform the animation
along side with. For example during a push on a `UINavigationController`.
*/
func setTabBar(
hidden: Bool,
animated: Bool = true,
along transitionCoordinator: UIViewControllerTransitionCoordinator? = nil
) {
guard isTabBarHidden != hidden else { return }
let offsetY = hidden ? tabBar.frame.height : -tabBar.frame.height
let endFrame = tabBar.frame.offsetBy(dx: 0, dy: offsetY)
let vc: UIViewController? = viewControllers?[selectedIndex]
var newInsets: UIEdgeInsets? = vc?.additionalSafeAreaInsets
let originalInsets = newInsets
newInsets?.bottom -= offsetY
/// Helper method for updating child view controller's safe area insets.
func set(childViewController cvc: UIViewController?, additionalSafeArea: UIEdgeInsets) {
cvc?.additionalSafeAreaInsets = additionalSafeArea
cvc?.view.setNeedsLayout()
}
// Update safe area insets for the current view controller before the animation takes place when hiding the bar.
if hidden, let insets = newInsets { set(childViewController: vc, additionalSafeArea: insets) }
guard animated else {
tabBar.frame = endFrame
return
}
// Perform animation with coordinato if one is given. Update safe area insets _after_ the animation is complete,
// if we're showing the tab bar.
weak var tabBarRef = self.tabBar
if let tc = transitionCoordinator {
tc.animateAlongsideTransition(in: self.view, animation: { _ in tabBarRef?.frame = endFrame }) { context in
if !hidden, let insets = context.isCancelled ? originalInsets : newInsets {
set(childViewController: vc, additionalSafeArea: insets)
}
}
} else {
UIView.animate(withDuration: 0.3, animations: { tabBarRef?.frame = endFrame }) { didFinish in
if !hidden, didFinish, let insets = newInsets {
set(childViewController: vc, additionalSafeArea: insets)
}
}
}
}
/// `true` if the tab bar is currently hidden.
var isTabBarHidden: Bool {
return !tabBar.frame.intersects(view.frame)
}
}
@fvvliet

This comment has been minimized.

Copy link

@fvvliet fvvliet commented May 17, 2018

This does not work properly on iPhone X...

@WhistlerW

This comment has been minimized.

Copy link

@WhistlerW WhistlerW commented Sep 27, 2019

extension UITabBarController {

func setTabBar(
    hidden: Bool
) {
    guard isTabBarHidden != hidden else { return }
    
    let offsetY = hidden ? tabBar.frame.height : -tabBar.frame.height
    let endFrame = tabBar.frame.offsetBy(dx: 0, dy: offsetY)
    let cvc: UIViewController? = viewControllers?[selectedIndex]
    var newInsets: UIEdgeInsets?
    if #available(iOS 11.0, *) {
        newInsets = cvc?.additionalSafeAreaInsets
    }
    
    weak var tabBarRef = self.tabBar
    UIView.animate(withDuration: 0.1, animations: {
        
    }, completion: { isFinished in
        var height: CGFloat = 0
        if #available(iOS 11.0, *) {
            height = self.hasBottomNotch ? offsetY + (UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0.0) : offsetY
        } else {
            height = offsetY
        }
        newInsets?.bottom -= height
        if #available(iOS 11.0, *) {
            cvc?.additionalSafeAreaInsets = newInsets!
        } else {
            cvc?.view.frame = CGRect(x: 0, y: 0,
                                     width: cvc?.view.frame.width ?? 0.00,
                                     height: (cvc?.view.frame.height ?? 0.00) + height)
        }
        if isFinished {
            UIView.animate(withDuration: 0.2, animations: {
                tabBarRef?.frame = endFrame
            }, completion: nil)
        }
    })
}

var isTabBarHidden: Bool {
    return !tabBar.frame.intersects(view.frame)
}

}

Refactored

@simme

This comment has been minimized.

Copy link
Owner Author

@simme simme commented Sep 27, 2019

Sweet! I'm not using this myself anymore, but maybe others have use for it :)

@fukemy

This comment has been minimized.

Copy link

@fukemy fukemy commented Mar 19, 2020

that only hide tabbar not tabbar item

@abishdangol

This comment has been minimized.

Copy link

@abishdangol abishdangol commented Apr 7, 2020

I have recently used this extension. I found out one thing that after hiding the tabbar and then sending the app to background. Then again opening the app the tabbar reappears.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment