Safe Area unaware of hidden tab bar

Any hints or experience with the safe area and a hidden tab bar on iPhone X would be appreciated!

We've been making updates to our app for iPhone X and we've run into one issue we haven't been able to resolve.


Our app uses a UITabBarController. On some screens that are hierarchically below the UITabBarController, we hide the tab bar. On these screens, we normally have a bottom action bar of our own making that has a couple of action buttons in it. We hide the tab bar because it's odd to have this action bar above a tab bar both visually and when touching buttons (because it can be easy to mistap and activate a tab when an action button was the target or vice-versa).


The problem occurs when we create one of these views. The view is defined via a UIViewController in an xib. If we create constraints from a subview (say, the bottom of a top level table view or the action bar itself) in the xib to the bottom of the safe area of the view controller's main view, the layout at runtime acts as though the tab bar is still visible even though it is hidden. So we have a space at the bottom of the screen that is the height of the bottom home button plus the tab bar height.


After looking for solutions that didn't require specific checks for an iPhone X and iOS 11 (because iOS 10 doesn't have the issue), I relented and started trying anything that could work. If I create two constraints, one with a zero constant to the bottom safe area and one that forces the main view downward by the height of the tab bar, and then only make one of them active depending on what device and OS version is being run, it appears to work. Until it doesn't.


The first layout of the screen on iPhone X will work, but if we then (for example) show a modal screen and then return to the first screen, the layout will be incorrect again. The bottom of the main view will go off the bottom of the screen.


Uhg.

Replies

I have the same issue. My app has a UITabBar at the bottom and view controllers within UINavigationControllers as content. On detail screens of the UINavigationController I hide the tab bar, but the safe layout guide looks like it still considers the tab bar to be visible.

I'm not sure if my answer is relevant, as 5 years left since lat post update...

But I'm facing the same issue in 2023. Found the solution works for me.

Just add this to the view controller you are going to push.


    private var originalEdgesForExtendedLayout: UIRectEdge = []
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.originalEdgesForExtendedLayout = self.edgesForExtendedLayout
        self.edgesForExtendedLayout.insert(.bottom)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        self.edgesForExtendedLayout = self.originalEdgesForExtendedLayout
    }

And don't forget to set hidesBottomBarWhenPushed to true right before the push called:

viewControllerToPush.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(viewControllerToPush, animated: true)

Just go to the Navigation Controller of the UITabBarController, choose a Translucent Tab Bar on the Bottom Bar of the simulated matrix ( or anything other than inferred). Choose the rest of the view controllers in the hierarchy as 'inferred'. You'll not see the space. This was for XCODE 15.1