How do I hide/show tabBar when tapped using Swift in iOS8 How do I hide/show tabBar when tapped using Swift in iOS8 swift swift

How do I hide/show tabBar when tapped using Swift in iOS8


After much hunting and trying out various methods to gracefully hide/show the UITabBar using Swift I was able to take this great solution by danh and convert it to Swift:

func setTabBarVisible(visible: Bool, animated: Bool) {    //* This cannot be called before viewDidLayoutSubviews(), because the frame is not set before this time    // bail if the current state matches the desired state    if (tabBarIsVisible() == visible) { return }    // get a frame calculation ready    let frame = self.tabBarController?.tabBar.frame    let height = frame?.size.height    let offsetY = (visible ? -height! : height)    // zero duration means no animation    let duration: TimeInterval = (animated ? 0.3 : 0.0)    //  animate the tabBar    if frame != nil {        UIView.animate(withDuration: duration) {            self.tabBarController?.tabBar.frame = frame!.offsetBy(dx: 0, dy: offsetY!)            return        }    }}func tabBarIsVisible() -> Bool {    return (self.tabBarController?.tabBar.frame.origin.y)! < self.view.frame.maxY}// Call the function from tap gesture recognizer added to your view (or button)@IBAction func tapped(_ sender: Any?) {    setTabBarVisible(visible: !tabBarIsVisible(), animated: true)}


Loved Michael Campsall's answer. Here's the same code as extension, if somebody is interested:

Swift 2.3

extension UITabBarController {    func setTabBarVisible(visible:Bool, animated:Bool) {        // bail if the current state matches the desired state        if (tabBarIsVisible() == visible) { return }        // get a frame calculation ready        let frame = self.tabBar.frame        let height = frame.size.height        let offsetY = (visible ? -height : height)        // animate the tabBar        UIView.animateWithDuration(animated ? 0.3 : 0.0) {            self.tabBar.frame = CGRectOffset(frame, 0, offsetY)            self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY)            self.view.setNeedsDisplay()            self.view.layoutIfNeeded()        }    }    func tabBarIsVisible() ->Bool {        return self.tabBar.frame.origin.y < CGRectGetMaxY(self.view.frame)    }}

Swift 3

extension UIViewController {    func setTabBarVisible(visible: Bool, animated: Bool) {        //* This cannot be called before viewDidLayoutSubviews(), because the frame is not set before this time        // bail if the current state matches the desired state        if (isTabBarVisible == visible) { return }        // get a frame calculation ready        let frame = self.tabBarController?.tabBar.frame        let height = frame?.size.height        let offsetY = (visible ? -height! : height)        // zero duration means no animation        let duration: TimeInterval = (animated ? 0.3 : 0.0)        //  animate the tabBar        if frame != nil {            UIView.animate(withDuration: duration) {                self.tabBarController?.tabBar.frame = frame!.offsetBy(dx: 0, dy: offsetY!)                return            }        }    }    var isTabBarVisible: Bool {        return (self.tabBarController?.tabBar.frame.origin.y ?? 0) < self.view.frame.maxY    }}


I had to adapt the accepted answer to this question a bit. It was hiding the bar but my view wasn't sizing itself appropriately so I was left with a space at the bottom.

The following code successfully animates the hiding of the tab bar while resizing the view to avoid that issue.

Updated for Swift 3 (now with less ugly code)

func setTabBarVisible(visible: Bool, animated: Bool) {    guard let frame = self.tabBarController?.tabBar.frame else { return }    let height = frame.size.height    let offsetY = (visible ? -height : height)    let duration: TimeInterval = (animated ? 0.3 : 0.0)    UIView.animate(withDuration: duration,                   delay: 0.0,                   options: UIViewAnimationOptions.curveEaseIn,                   animations: { [weak self] () -> Void in                    guard let weakSelf = self else { return }                    weakSelf.tabBarController?.tabBar.frame = frame.offsetBy(dx: 0, dy: offsetY)                    weakSelf.view.frame = CGRect(x: 0, y: 0, width: weakSelf.view.frame.width, height: weakSelf.view.frame.height + offsetY)                    weakSelf.view.setNeedsDisplay()                    weakSelf.view.layoutIfNeeded()    })}func handleTap(recognizer: UITapGestureRecognizer) {    setTabBarVisible(visible: !tabBarIsVisible(), animated: true)}func tabBarIsVisible() -> Bool {    guard let tabBar = tabBarController?.tabBar else { return false }    return tabBar.frame.origin.y < UIScreen.main.bounds.height}

Older Swift 2 Version

func setTabBarVisible(visible: Bool, animated: Bool) {    // hide tab bar    let frame = self.tabBarController?.tabBar.frame    let height = frame?.size.height    var offsetY = (visible ? -height! : height)    println ("offsetY = \(offsetY)")    // zero duration means no animation    let duration:NSTimeInterval = (animated ? 0.3 : 0.0)    // animate tabBar    if frame != nil {        UIView.animateWithDuration(duration) {            self.tabBarController?.tabBar.frame = CGRectOffset(frame!, 0, offsetY!)            self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY!)            self.view.setNeedsDisplay()            self.view.layoutIfNeeded()            return        }    }}@IBAction func handleTap(recognizer: UITapGestureRecognizer) {    setTabBarVisible(!tabBarIsVisible(), animated: true)}func tabBarIsVisible() -> Bool {    return self.tabBarController?.tabBar.frame.origin.y < UIScreen.mainScreen().bounds.height}