twhitbeck
twhitbeck

Reputation: 113

UITabBarController inside UINavigationController works on iOS 8 but not 7

In iOS 7 for a view controller in a UITabBarController in a UINavigationController, the navigation bar covers up content. In iOS 8 this is not the case, and items which have constraints in relation to the Top Layout Guide are perfectly positioned.

If I embed each tab's view controller in a UINavigationController, then everything looks good in iOS 7, but in iOS 8 there's a white gap between the navigation bar and the content of the view controllers.

I understand that Apple explicitly forbids this in their documentation. A UITabBarController should not be pushed onto a UINavigationController's stack. But this is the effect that I want to achieve:

Start app at a login screen (this will be root of a UINavigationController). There is no tab bar yet. If login is successful, push a new UITabBarController onto the stack. At this point, the logged in user can switch between different parts of the app by switching tabs.

Is there a workaround? Or is there a different way to achieve this effect?

Upvotes: 1

Views: 512

Answers (2)

eyeezzi
eyeezzi

Reputation: 635

I had this same issue recently, I came up with 2 approaches. I'll use Swift 3.0 for clarity. Hope this saves someone out there some time.

Assumptions
Your app starts with a UINavigationController which embeds your LoginController

Approach 1: Using the app window (recommended)
In your LoginController, when the user logs in, simply change the rootViewController property of your app's keyWindow to your desired UITabBarController

// LoginController: onLogin
let homeTBC = UITabBarController()
UIApplication.shared.keyWindow?.rootViewController = homeTBC

Approach 2: Using the UINavigationController's stack
In your LoginController, when the user logs in, make your desired UITabBarController the root view controller of your navigationController.

// LoginController: onLogin
let homeTBC = UITabBarController()
self.navigationController?.viewControllers = [homeTBC]

The caveat with this method is that the viewControllers in your homeTBC can not directly access the navigationBar, they would have to go through their mother-tabBarController, for example, to change the title in one of the viewControllers in your homeTBC, you'd have to do this:

self.tabBarController?.navigationItem.title = "My VC Title"

Upvotes: 1

twhitbeck
twhitbeck

Reputation: 113

Couldn't find a satisfactory way to go about it. I ended up restructuring the app so that the UITabBarController was the root and the Login view controller was presented modally initially.

Upvotes: 1

Related Questions