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 commented May 17, 2018

This does not work properly on iPhone X...

@WhistlerW

This comment has been minimized.

Copy link

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 commented Sep 27, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.