Created
January 25, 2018 15:36
-
-
Save simme/a44cd16f89038cbee8537b89d237386b to your computer and use it in GitHub Desktop.
Extension on UITabBarController for hiding/showing the tab bar.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I found this leaves a blank space if the view controller in your tab bar is a UIHostingViewController.
Heres the fix: