Children UIViewControllers of UITabBarController overlapping Status Bar - ios

Xcode 7
iOS Target 9.3
Swift 2
I have created a new Tabbed Application in Xcode:
I changed the background of the first template generated UIViewController super view to gray and then I run the app, as you can see in this screenshot the First UIView is overlapped by the Status Bar:
I have read many articles, particulary specified to iOS 7 regarding allocating space for the Status Bar.
I also read on apple.developer.com the following quote:
"Applications that use an opaque UINavigationController or UITabBarController automatically keep their content below the status bar."
In general this link on the apple.developer.com website does seem a bit outdated.
But, with that said, I am expecting the UITabBarController to load the tabbed children views with with space allocated for the status as displayed in the Storyboard for the UITabBarController:
I have tried adding the following to my UITabBarController class:
override func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = UIRectEdge.None
self.automaticallyAdjustsScrollViewInsets = false;
}
I have looked at many Stackoverflow question and answer threads, I found this person asking the same question on Stackoverflow:
Using UITabBarController but status bar covers view
I do know how to add a constraint to the Top Layout Guide to each parent view in each UiViewController tab but I am trying to avoid adding a new top level UIView because my existing UIViewControllers tabs all have UILabels, UIButtons, UICollections, etc in the SuperView I cannot add a constraint to Top Layout Guide to the SuperView in Xcode Storyboard.
With the SuperView I cannot add a Top Level Constraint by Control Dragging it seems:

iOS handles this for you inside of auto layout. Whilst the view extends underneath the status bar, fix your constraints to be 0 distance in the 'Vertical Spacing to top layout guide' constraint and you will find it sits underneath the status bar as expected.

So I found through the help of #SeanCAtkinson that things are working as the should. I needed add a constraint to the Top Layout guide for any UIViewController that was a tab aka a child of my UITabBarController.
I thought any child that was tab would be displayed with spaced allocated for the Status bar. I thought UITabBarController was doing that, based on how it looks in the Xcode 7 Storyboard:
As you can see from the screenshot, the UITabBarController implies that tabs will display within the light grey square, which you can see has top "guid" below the status bar.
It just isn't the case the UITabBarController will stop the Status Bar from overlapping children tabs whether UIViewControllers, UICollectionViewControllers or UITableViewControllers, etc. You have to use the Top Layout Guide constraint your children tabs.
What partcularly confusing is that a SuperView cannot have the Top Layout guide contraint, the SuperView will always be full screen.

Related

UIViewController - top misaligned at cold launch on iOS 9/10, ok on 11

I have a UIViewController that contains a UISegmentControl at the top, and a UITableView below. The layout is very simple. The UISegmentControl Top Margin is 16pts from the Top Layout Guide. The tableView is relative to the UISegmentControl. The view is part of a UITabBarController set. The UITabBarController is the storyboard's initial view controller.
I'm experiencing a problem where, on iOS 9 and 10, the UISegmentControl and the UITableView are positioned too high at initial app launch. As a result the UISegmentControl is partially obscured. If I switch to another tab or the next view in the hierarchy (by tapping a table cell), then go back to this view, the problem resolves itself.
The problem does not occur on iOS 11. The app doesn't support anything earlier than iOS 9.
Here are screenshots, taken both immediate after launch and then after switching to another tab then back again. Any suggestions appreciated.
Turn off extend edges under top bar :
Check your view controller attributes inspector in IB. Look for
"Extend Edges" option under View Controller, and uncheck "Under Top
Bars" if it is checked.

How to remove white top space that appears on tab in others (UITabBarController)

I am working on Xamarin Studio with Mono but you can respond in Obj-C or Swift I don't mind. (Please don't mind the icons, design, translations, etc on the screenshots this is WIP)
I have this strange issue I can't resolve :
A white blank space appears under the top bar of my UIView which is in a UITabBarController, at first I thought it was the "Adjust Scroll View Insets" option enabled but it is not. I also tried to remove my UIWebView and try with a Label, same problem.
The blank space only appears on views that are "tabbed" in the "Others" section of my UITabBarController (when the screen is too small). You can see on my screenshots on an iPad the white space is not here, but on every other devices (iPhone, iPhone plus) it appears !
I can put a negative top constraint if the device is not an iPad but it is not the proper way to remove it ...
You can find the screenshots of (in order) :
The storyboard view
Top Constraint of the WebView
The whitespace on iPhone (but not on iPad and Storyboard, shouldn't be here !!)
StoryBoard structure
No whitespace on iPad (this is the normal behaviour, I want it on smaller devices too)
ViewController parameters
That by sight the white space is exactly the nav bar is a giveaway that in adjusting for those bars something is awry.
There is a contradiction in your layout that is probably the source of the issue. You have "extend edges" selected for the map view, but you have the top of the map view constrained to the top layout guide. The top layout guide is located at the bottom of the nav bar, so if something was adjusting insets for being under the bar, and knew the bar height and assumed it was under the bar, then this would result.
That wouldn't explain why it looks correct when included in the tab bar's initial view controllers, but it's possible when it appears from more pop-up, it is added to the view hierarchy so quickly it doesn't know the exact position of the top layout guide or the top bars, and so causes the glitch, whereas in the tab bar controller tabs it makes that adjustment on one of multiple layout passes.
Thank you for your answers, I found out what was that white space.
If I want to remove it I have to uncheck "Extent edges - Under Top Bars" and then do (or the NavigationBar will be gray, see Dark shadow on navigation bar during segue transition after upgrading to Xcode 5.1 and iOS 7.1):
NavigationController.NavigationBar.Translucent = false;
But trying to resolve the issue, I tried the following code :
ParentViewController.NavigationController.NavigationBar.Translucent = false;
And the white space turned into a second NavigationBar with tools to reorganize the tabs, and no need to uncheck "Extent edges - Under Top Bars" (especially if you don't set the tranlucent to false because the second navigation bar will go under it).
I will keep that second NavigationBar (https://developer.apple.com/reference/uikit/uitabbarcontroller/1621183-morenavigationcontroller), I like it. But for some reason it wasn't displayed until I set the ParentViewController NavigationController NavigationBar Translucent to false ... I don't really get why, it should have appeared directly but ...
Note that the proper way to display this NavigationBar if it is not displayed by default is to add the line in the UITabBarController class, and not in each ViewController ...
public partial class TabBarController : UITabBarController
{
public TabBarController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
CustomizableViewControllers = null; //if you want to disable the edit button
NavigationController.NavigationBar.Translucent = false;
base.ViewDidLoad();
}
}
(Sorry for the french on the screenshots my device is in French ..)

Embedding a Collection View inside a Container View - extra white-space at top

I have an app that uses a Nav Contoller as it's initial VC, which then has a root UIViewContoller that contains a UIView at the top half, and a UIContainerView at the bottom. In the UIContanerView, I'm embedding a working UICollectionView that contains image buttons that segue to detail views.
The problem is that white space now shows up at the top of the UICollectionView. Given this is around 64 pixels high, it appears to be a ghosting of a Nav Bar 44px + Status Bar 20px = 64.
And if I scroll up everything looks fine and works as expected, and it also allows me to show you what I expected the layout to look like upon launch:
A snippet of my storyboard is below if that helps:
yes, that could be because child view controller embedded in container view gets the impression, that it is a direct child of UINavigationController, which in turn make collectionView leave top 64 pt insets.
TO solve this problem,In your child view controller interface builder, unmark adjust scrollView insets
This should solve your problem
UPDATE
As Dan suggested, we can also fix it programatically, by calling
automaticallyAdjustsScrollViewInsets = false
in viewDidLoad() of your UIViewController

UIViewController auto layout in iOS8

After updating device to iOS 8 the next issues with layout occur.
I have an UITabBarController which contains two UITableViewController embedded in UINavigationController. This is main view.
Also there are several UIViewControllers designed in StoryBoard (not embedded in UINavigationViewControllers). These are secondary views. All of them have "Hide Bottom bar on Push" set to YES. Constraints are set to determine layout.
All secondary views are shown with:
UIStoryboard* sb = [UIStoryboard storyboardWithName:STORYBOARD_NAME bundle:nil];
UIViewController* secondaryView = [sb instantiateViewControllerWithIdentifier:_name];
[navigationController pushViewController:secondaryView animated:YES];
All works fine on iOS7.
But with iOS8 there are some problems when secondary view controller appears:
All pinned to bottom UIViews are shown on wrong places for a moment and then "jump" to correct place. Looks like first position is calculated including bottom bar (which is hidden due to "Hide on Push")
If there is UITableView as subview: top pinned subviews again are show on wrong place for a moment and then "jump" to correct place. Looks like first position is calculated not including navigation bar size. If i remove UITableView from controller - all works fine (except p.1)
Tried to set Simulated metrics for secondary views - did not help.
These "jumps" are really annoying. Would appreciate for any advices.
I had a similar problem with jumping when hiding the tab bar from the Storyboard.
Make sure your bottom subviews are pinned to the superview rather than the Bottom Layout Constraint.
You have to do this from the menu - Editor - Pin - Bottom Space to Superview, because the Auto Layout menu in Interface Builder pins to Bottom Layout Constraint by default.
As far as i experienced iOS 8 have issue in tabbar controller mixed with navigation bar controller .. removing one of them will make it run ok again.

How to make a UITableViewController subclass respect topLayoutGuide in iOS7?

in my app I have a simple UITableViewController that's just plain Objective-C code, no .xib or storyboard involved. It represents the contents of one tab in a tab bar.
Since iOS 7 its contents are overlapped by the status bar at the top and tab bar at the bottom.
Using only code, how can I make the table view add space at the top and bottom to align with topLayoutGuide and bottomLayoutGuide?
I know about
self.edgesForExtendedLayout=UIRectEdgeNone;
but that seems to simply shrink the table view to not intersect the tab bar and to disable the transparency of the tab bar. Instead I'd like the table view to add some padding.
Thanks!
Update:
I've also tried explicitly setting automaticallyAdjustsScrollViewInsets to YES, but that didn't help either (should be the default behavior anyway).
It seems this is not (yet) supported, at least for programmatically created UITableViewControllers without an UINavigationController that's embedding them.
I checked the position for both layout guides, and at run-time both off-sets read 0 distance from the edges of the screen. Hence automaticallyAdjustsScrollViewInsets won't set the insets correctly.
So now I actually modify my first section header and last section footer manually to add 21 pixels at the top and 50 pixels at the bottom respectively.
Bummer. :-(

Resources