hide / show tab bar when push / back. swift
Asked Answered
C

6

12

Answer: Use self.tabBarController?.tabBar.hidden instead of hidesBottomBarWhenPushed in each view controller to manage whether the view controller should show a tab bar or not.

override func viewWillAppear(animated: Bool) {
    self.tabBarController?.tabBar.hidden = true/false
} 

I want

view controller 1: tab bar should be showed

view controller 2: tab bar should be showed

view controller 3: tab bar should not be showed.

view controller 4: tab bar should not be showed.

I wrote

// prepareForSegue in view controller 1, 
    let upcoming = segue.destinationViewController as! viewcontroller3
    upcoming.hidesBottomBarWhenPushed = true

// in view controller 3,
    func clickOnButton(button: UIButton) {
        self.hidesBottomBarWhenPushed = false
        self.performSegueWithIdentifier("viewController2", sender: self)
        self.hidesBottomBarWhenPushed = true
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "viewController2" {
            let upcoming = segue.destinationViewController as! viewController2
            upcoming.hidesBottomBarWhenPushed = false
        }
    }
// prepareForSegue in view controller 2
    let upcoming = segue.destinationViewController as! viewController4
    upcoming.hidesBottomBarWhenPushed = true

if 1 -> 3 then back to 1, works.

if 1 -> 3 -> 2 then back to 3 and back to 1, works.

if 2 -> 4, then back to 2, works.

if 1 -> 3 -> 2 -> 4 then back to 2, tab bar is not showed. Wondering why. Any suggestions or some explanation of hidesBottomBarWhenPushed as it confuses me a lot

enter image description here

Capriole answered 16/2, 2016 at 8:13 Comment(1)
Did you saw bottom bar when you nav from 3 to 2 ?Antimasque
A
36

As it's name suggest, hiddenBottomBarWhenPushed only hide bottom bar if needed, it will not unhide bottomBar. You can do this to get it works:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.tabBarController?.tabBar.hidden = true/false
} 

or simply put self.tabBarController?.tabBar.hidden = true/false in prepareForSegue

But I would not recommend you to do so, as it would be weird if bottomBar suddenly popped out, user will thought they suddenly back to rootViewController while they are not.

Users should always know where they are in your app and how to get to their next destination.

Antimasque answered 16/2, 2016 at 8:51 Comment(3)
If i do it in viewWillAppear, I didn't see the pop out. But, if I do it in viewDidAppear, I do see the pop out. The reason why I want to hide the tab bar in 3 and 4 is because 3 is 1 to 1 chat and 4 is a group chat. And, I cross out all the hidesBottomBarWhenPushed and use tabBar.hidden in viewWillAppear in each view controller.Capriole
Hiding tab bar in 3 and 4 is normal behavior , but if you are going to nav from 3 to 2 , it may not be appropriate to show tab bar. BTW if you use tabBar.hidden in viewWillAppear of 2 , you may not saw tabBar if click tabBarItem directly, so it may be better to put it in prepareForSegue of 3.Antimasque
for swift 4 : isHiddenTribble
P
8

Add hidesBottomBarWhenPushed property to destination view controller, and set to true.

Example with push VC with identifier:

    let storyboard = UIStoryboard(name: STORYBOARD_NAME, bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: VC_IDENTIFIER) as! YourViewController
    vc.hidesBottomBarWhenPushed = true
    navigationController?.pushViewController(vc, animated: true)
Psychosocial answered 10/9, 2018 at 8:59 Comment(0)
D
7

Here's my two cents. Swift 3/4/5:

Approach 1: (Recommended)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "YourSegueIdentifier" {
        let destinationController = segue.destinationViewController as! YourViewController
        destinationController.hidesBottomBarWhenPushed = true // Does all the hide/show work.
    }
}

Approach 2:

override func viewWillAppear(_ animated: Bool) { // As soon as vc appears
    super.viewWillAppear(true)
    self.tabBarController?.tabBar.isHidden = false
}

override func viewWillDisappear(_ animated: Bool) { // As soon as vc disappears
    super.viewWillDisappear(true)
    self.tabBarController?.tabBar.isHidden = true
}
Detonator answered 2/4, 2019 at 6:29 Comment(0)
T
5

Add this implementation in ViewController you want to hide/show tabbar on pushed/popped. it will also work for all next pushed view controllers.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if wilmove {
        hidesBottomBarWhenPushed = true
    }
    wilmove = false
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if wilmove {
        hidesBottomBarWhenPushed = false
    }
    wilmove = false
}

var wilmove = false
override func willMove(toParentViewController parent: UIViewController?) {
    super.willMove(toParentViewController: parent)
    wilmove = true
    if !isViewLoaded {
        hidesBottomBarWhenPushed = true
    }
}
Tapes answered 15/9, 2017 at 7:39 Comment(0)
E
3

Swift 5

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    self.hidesBottomBarWhenPushed = true
}
Elliot answered 17/3, 2021 at 4:19 Comment(0)
K
2

It's Better to Fade Out than to Hide Away...

(.... my my, hey hey)

Swift 5:

Yet another approach... is to fade the tab bar in and out.. Not saying this is strategically more advantageous than any of the other ones, such as those entailing prepareForSegue, but it can be adapted to other triggers. In any case, animating tab bar alpha avoids the harsh disappear/appear effect when setting .isHidden on the tabBar (UIView) by fading it in and out. This is done in any VC that needs it hidden when the VC is pushed or loaded and unhidden when the VC is popped or unloaded.

This will not bother to reinstate the tab bar until the back button is pushed in the navBar or equivalent action, such that when a child VC is pushed onto it, the tab bar will remain hidden, which usually (but doesn't always) makes sense.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    UIView.animate(withDuration: 0.4, delay: 0.0, options: UIView.AnimationOptions.curveEaseOut, animations: {
        self.tabBarController?.tabBar.alpha = 0.0
    }, completion: { (finished: Bool) -> Void in
        self.tabBarController?.tabBar.isUserInteractionEnabled = false

    })
}

override func viewWillDisappear(_ animated: Bool) {
    if self.isMovingFromParent {
        UIView.animate(withDuration: 0.4, delay: 0.0, options: UIView.AnimationOptions.curveEaseOut, animations: {
            self.tabBarController?.tabBar.alpha = 1.0
        }, completion: { (finished: Bool) -> Void in
            self.tabBarController?.tabBar.isUserInteractionEnabled = true
        })
    }
}
Kettledrummer answered 2/5, 2022 at 5:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.