Swift UITabBarController hide with animation

In case if you need to toggle it from hide to visible and vice versa:

func toggleTabbar() {
    guard var frame = tabBarController?.tabBar.frame else { return }
    let hidden = frame.origin.y == view.frame.size.height
    frame.origin.y = hidden ? view.frame.size.height - frame.size.height : view.frame.size.height
    UIView.animate(withDuration: 0.3) {
        self.tabBarController?.tabBar.frame = frame
    }
}

I've developed a util extension for UIViewController
Swift 4 compatible:

extension UIViewController {

    func setTabBarHidden(_ hidden: Bool, animated: Bool = true, duration: TimeInterval = 0.3) {
        if animated {
            if let frame = self.tabBarController?.tabBar.frame {
                let factor: CGFloat = hidden ? 1 : -1
                let y = frame.origin.y + (frame.size.height * factor)
                UIView.animate(withDuration: duration, animations: {
                    self.tabBarController?.tabBar.frame = CGRect(x: frame.origin.x, y: y, width: frame.width, height: frame.height)
                })
                return
            }
        }
        self.tabBarController?.tabBar.isHidden = hidden
    }

}

You could change the tab bar's frame inside an animation, so something like:

func hideTabBar() {
    var frame = self.tabBarController?.tabBar.frame
    frame?.origin.y = self.view.frame.size.height + (frame?.size.height)!
    UIView.animate(withDuration: 0.5, animations: {
        self.tabBarController?.tabBar.frame = frame!
    })
}

func showTabBar() {
    var frame = self.tabBarController?.tabBar.frame
    frame?.origin.y = self.view.frame.size.height - (frame?.size.height)!
    UIView.animate(withDuration: 0.5, animations: {
        self.tabBarController?.tabBar.frame = frame!
    })
}

Which sets the tab bar just below the visible screen, so that it slides up/down from the bottom.


Improvement of the response of @Luca Davanzo. If the bar is already hidden, it will continue hiding it and moving it lower. Also get rid of the return, so the state of the tabbar.hidden changes when the animation happens. So I added a check:

extension UIViewController {

func setTabBarHidden(_ hidden: Bool, animated: Bool = true, duration: TimeInterval = 0.5) {
    if self.tabBarController?.tabBar.isHidden != hidden{
        if animated {
            //Show the tabbar before the animation in case it has to appear
            if (self.tabBarController?.tabBar.isHidden)!{
                self.tabBarController?.tabBar.isHidden = hidden
            }
            if let frame = self.tabBarController?.tabBar.frame {
                let factor: CGFloat = hidden ? 1 : -1
                let y = frame.origin.y + (frame.size.height * factor)
                UIView.animate(withDuration: duration, animations: {
                    self.tabBarController?.tabBar.frame = CGRect(x: frame.origin.x, y: y, width: frame.width, height: frame.height)
                }) { (bool) in
                    //hide the tabbar after the animation in case ti has to be hidden
                    if (!(self.tabBarController?.tabBar.isHidden)!){
                        self.tabBarController?.tabBar.isHidden = hidden
                    }
                }
            }
        }
    }
}

}