I'm working on a universal app, and I'm trying to share as much code as possible between the iPhone and iPad versions. I need to use a TabBarController as my root view controller and though I'd like to use a SplitViewController in each of the tabs, SplitViewController's docs say it needs to be the root view controller. So, with all of that in mind - understand that I'm attempting to place two navigation controllers side-by-side and (mostly) replicate the behavior/layout of a SplitViewController.
Everything works just fine, except for the layout of the views. When the app is started in portrait mode, everything functions and resizes/positions correctly when the device orientation changes.
If the app is started in any orientation other than UIDeviceOrientationPortrait, the view displays with a 20 point gap/margin above the navigation controller. I've tried adjusting the frame at runtime with no perfect result. Adjusting the origin.y of the frame to -20 and increasing the height by 20 brings the view flush with the top of it's parent, but it leaves a 20 point gap at the bottom!
I solved this in my app by hiding then showing the navigation bar after adding the navigation controllers view. eg.
had a similar problem with the unwanted gap between the status bar and the view directly
below
it, solved it by going toautosizing
in interface builder and setting the view in question to stick to the top of its parent view.UINavigationController is normally displayed as a full-screen controller, which means that (when displayed as the root view controller of the window) the top part of its view is placed under the status bar. It then manually positions its navigation bar and content view to not underlap the status bar when the status bar is visible. Unfortunately, it doesn't really handle things correctly when it is being positioned by some other view controller, it (sometimes) assumes it needs to leave that 20px gap without checking whether its view actually is under the status bar.
The solution is to set
wantsFullScreenLayout
on the UINavigationController to NO, so it won't even attempt to leave that gap for the status bar.Not sure whether it'll be of any help, but I've had similar issues in the past and have been able to resolve this by setting the frame of the UINavigationController view to CGRectZero when adding it to its superview.
In layoutSubviews I update the frame of the UINavigationController view of course.
This is a common issue when adding view controllers to a tab bar.
From Apple's documentation (Tab Bar Controllers - Tab Bars and Full-Screen Layout):
In words of code, you should do the following:
If, however, you run into the problem that when opening application in orientation other than
UIInterfaceOrientationPortrait
yourmyNavController
's view moves 20 pix off the screen to the top, then you will have set controller'swantsFullScreenLayout
property dynamically (instead of the above solution), depending on the initial orientation. I do it using a static variable defined in your navigation controller implementation:After that you need to overload the
viewDidAppear:
method and set the variable appropriately:Hope this helps.
I was able to brute force as follows. In
viewDidLoad
orloadView
:And in viewDidAppear:
It's ugly, but it seems to work.