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

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.

Related

Children UIViewControllers of UITabBarController overlapping Status Bar

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.

XCode 7 and iOS 8 Auto Layout top constraint issue

I recently updated my XCode 6.3 to 7 and strange things started to happen with my auto layout constraints in the storyboard.
My app uses UITabBarController with three tabs. The initial tab has a UICollectionView with top constraint set to 44px from the top layout guide (there is a toolbar in the embedding UINavigationController.
When I run the app on iOS 7.1 (iPhone 4), everything looks fine. The collection view doesn't go bellow the toolbar. However in iOS 8.4 (iPhone 6) the collection view goes bellow the toolbar UNLESS I switch tabs and go back to the first one, where the collection view is positioned where it should be.
What I did:
Unchecked all "Extend edges under...." for every view controller in the chain
Set all simulated metrics for Status/Top/Bottom bars to "None" in every view controller in the chain
I had the idea to check for #available(iOS 8.0, *) and extend the constraint constant +20 pixels. But when I switch back to this tab, the collection view goes 20 pixels lower than where it should be.
So, I guess something happens to the view controllers when I switch tabs. What is it? Or is there any solution. I'm on a deadline and this is the only problem I have with my app.
p.s. I can provide source code and XCode screen shots if needed. But still, I think it's something more theoretical, than practical.
1) click on your UITabBarController in storyboard->identity inspector
2) uncheck "Adjust Scroll View Insets"
repeat for individual view controllers inside UITabBarController
Sometimes this happen also to me. I suggest replacing the top layout constraint with an height constraint equal to the view of the ViewController, this resolved my problem.

ios7 tableView is not corrently positioned with top layout guide

I'm making UIViewController with UITableView on it. I would like this tableview to act like "Notes" default app (when you scroll table content is blurred under nav bar).
As far as I understand I must put my tableView BELOW Top Layout Guide. If I do it, content don't go under nav bar (because top layout guide is below nav bar).
If I put tableView above Top Layout Guide content "blurred" under nav bar and first table is hidden, and on iOs6 is upper part of tableview is hidden.
Should I manually set content offset based on iOS version? I can't use self.topLayoutGuide inside viewController as it was introduced only in iOs7.
View hierarchy
UINavigationController -> UiViewController
\
- UIView
\
- UITableView
Everything is built in storyboard
Since you are targeting more than OS version, then I think you should handle your UI depending on the OS version.
So, yes, I do recommend setting self.topLayoutGuide within your code depending on the OS version.

In iOS 7, how do you access the topLayoutGuide / bottomLayoutGuide in Interface Builder?

Using XCode 5, downloaded today. iOS 7. When I run app the table view header appears underneath the navigation bar, I don't mind it scrolling underneath the navbar but I'd like for it to appear unobstructed initially. I am trying to figure out how to use the topLayoutGuide mentioned in the iOS 7 transition guide, which says you can set a constraint relative to it, but doesn't explain how.
Anyone know?
Transition guide here:
http://tinyurl.com/mgdl4sg
Just realized that my storyboard was still set to XCode 4.6
You have to go to the File Inspector (icon that looks like a file icon in the right navigation panel in Xcode) and then under "Interface Builder Document" where it says "Opens in" change to Default (5.0) and / or "View as" iOS 7.0 and Later
Then your IB document will show the guides inside the left hand navigation panel under the view controller
Often if you select the view, and click the "Pin" button at the bottom right, pin the vertical spacing, and the dropdown will have an option to use the topLayoutGuide
In my Storyboard, was still have trouble getting my UITableView to pin the vertical spacing between the top of the table view and the top layout guide. Every time I control-dragged I would get it pinning to the bottom of the table view instead of the bottom. But then I tried manually dragging the table view so that it appeared below the nav bar in IB and then control-dragged and the vertical spacing finally worked.
I had the same problem, and in Storyboard when I set the top bar to Opaque the top of the scrollView changed so that it wasn't obscured by the nav bar. Makes sense, but it's unfortunate that you can't use a translucent nav bar and get the same effect.

Toolbar hiding on rotated UISplitView DetailView

I've based my app on Apple's SplitView project type. I have a TableView as the Master, and am using different types of views as the Detail view. To select types of detail view, I'm using the fancy concept of buttons on my DetailView toolbar. When the DetailView is derived from UIViewController, everything is good. When the DetailView derives from UIViewController, but contains a UITableView then I have problems. In portrait view the toolbar is visible. In landscape mode the toolbar is hidden, even though the Tableview is moved down to allow space for it. The UIToolbar and UITableView are both defined in my NIB file which is loaded to create the detail view. Why is my toolbar invisible in landscape?
BTW, is this the best way to choose Detail view types with UISplitView? Bonus question, what if selecting a row in my DetailView tableview should bring up another View, I can't push it like I would with a NaviagtionController, so how do I go back to the detail tableview?
Thanks, Gerry
HI Gerry,
I have faced the same toolbar problem, when trying to rotate the splitView, toolbar will disappear. If you are creating the toolbar in the interface builder, try to set the toolbar properties(size), by selecting the toolbar, then --> Tools -->Size inspector, in the autosizing section, mark the left, right and upper red lines and unmark the bottom red line, then everything will works fine.
-Maria
Bonus question, I would create a UINavigationController in code, set it's rootcontroller to the DetailView tableview (self) and then push the new view on top of it.
When you react to the rotation change are you using the same view or a different one for the detail view? Seems like the new view may not contain an instance of the toolbar? Or the Tableview is covering it up because the landscape view has less vertical room than the portrait view. Are you resetting the height of the tableview to allow space for the toolbar within the 768 height when rotating to landscape?
Just a tip but whenever I run into odd things like this I remove the elements from the NIB file and create them programmatically in code and it usually solves the problem. You get a lot more control over things when you do. Overall as I've gained more experience with programming for iPhone OS I've found that I rarely put much into a NIB file any longer and do almost everything in code now.

Resources