UITableView behind NavigationBar after setting constraints - ios

I've added a TableView to my ViewController.
I have set the constraints like this:
Yet when i run the project the top of the firstcell(like 40px) is behind the NavigationBar:
What am i doing wrong here? Why is the TableView behind the navigationControllerBar?

Do not just set the constraint to 50, that's wrong on so many levels.
Constrain table view's top to top layout guide of view controller. This is gonna handle rotations for you as well. In landscape the navigation bar might have smaller height, this accounts for it as well. If you set it to 50 it's probably gonna look ridiculous.
Or pin the table view to the top of the superview as you do and set the contentInset property to the height of bars (this is useful if you wanna have translucent navigation bar and see the cells under navigation bar while you scroll). You can do this in code or storyboard:

You're not accounting for the navigation bar using the constraints. Set the top constraint to 50.
Since the scene in the Interface builder does not have a navigation bar - the constraints are not considering it and y (top) is set to 0 on the view, which does not have a navigation bar.
Either set the top constraint to 50 or put a bar in the view and set the top constraint to it.

Related

How do I move UINavigationBar under status bar and keep height for landscape and horizontal iPhone?

I have added UINavigationBar to UIView with custom backgroundColor and all I need to achieve is:
the same background for status bar when it is displayed
always the same height for UINavigationBar for both cases: status bar is displayed or not.
Pretty simple solution:
Just add four magic constraints in your storyboard:
The most interesting constraint is the last one. How do we add it?
move your UINavigationBar some points from the top (leave the space between your bar and top layout guide)
simply add constraint (ctrl + drag) from your bar to top layout guide and set its constant to 44.
then edit just added constraint, and change first item from top to bottom like in the image below:

Vertical space constraint strange behavior

I am trying to implement UIScrollView from Storyboard using Interface Builder. The ViewController im working on have UINavigationBar.
This is the steps i perform within my Storyboard
adding UIScrollView and set the top, bottom, left, right spacing to 0 (not to margins).
add UIView and set it to be a child of the scrollView. set its spacing to: top, left, right to 0 and it width and hight to the value listed, also set spacing to bottom of the viewcontroller.
The strange behavior is that the top constraint get way high than expected,
What am i missing here?
Thanks!
Well what you can do is select your view controller from the heirarchy on the left and in the attributes inspector uncheck "adjust scroll view insets".

How to fit tableview to superview below navigation bar via storyboard autolayout

I want to create a scroll disabled tableview which will fill the view below navigation bar. Finally I've managed to do it but it's not the right way because I'm giving minus 64 margin (status bar + navigation bar) to tableview.
I'm assigning my constraints from storyboard. I've tried lots of other constraints with the table view like giving zero constraints from 4 sides or
equal width + equal height + center horizontal + center vertical none of them worked.
What is the right way to solve this problem.
Screenshot from the storyboard are below.
I solved it.
unchecking four of them and adding the constraints from image below worked as I wanted.
So I guess scroll disabled tableviews not working as expected with these four view controller options checked.
As kerem keskin said, unchecking resolves the issue but you don't need to uncheck all four. Just need to uncheck Adjust Scroll View Inset.
Refer to this: iOS 7 -- navigationController is setting the contentInset and ContentOffset of my UIScrollView

Layout TableView with navigation bar and tool bar

I placed TableView on a middle of a layout with constraints to stay aligned with top/bottom guide bars and left/right sides.
When I insert prototype cell it doesn't go to the top and it's the same at run time. Seems like TableView holds space on top for something?
How do I make first cell to appear on top?
In your storyboard, adjust scroll view insets of your view controller is selected by default.
The best way to solve this problem is to add top and bottom constrains between the table view and its super view, instead of the layout guide, because the view controller will adjust the insects of the table view automatically.
By default, iOS adds a content inset on the UITableView. There are two solutions. You could either set the layout constraints to the top and bottom of the view instead of the top and bottom layout guides, or you could click on the view controller and in the attributes inspector, disable Extend Edges for Under Top Bars and Under Bottom Bars.

Working with Top Layout Guide in UIScrollView through Auto Layout

I want to use the Top Layout Guide in the UIScrollView through Auto Layout. Without the UIScrollView Auto Layout works well with Top Layout Guide.
But when I embed the UIButton in UIScrollView, it doesn't.
I know that is because UIScrollView is not the same hierarchy level with Top Layout Guide. But I think there may be a good solution to resolve this issue.
You are right to be confused. It is a bit counterintuitive but the top and bottom layout guides are irrelevant to configuring a UIScrollView so that its scrollable content will underlap the translucent navigation bar, which is the effect you are trying to achieve.
what to do
Given the view hierarchy you've shown in the second picture, this is what you need to do on iOS8:
Configure the view controller so that "Extend Edges Under Top Bar" is checked (in code, use edgesForExtendedLayout). This will ensure that the view controller's lays out its root view so that it underlaps the nav bar.
Configure the scroll view constraints so that the scroll view's top edge has a zero offset from the top edge of its superview, not zero space from the top layout guide. This will ensure that the collection view fills the root view and thus also underlaps the nav bar, which is necessary for the scroll view's content to be able to scroll under the nav bar. (IB might fight you on this. See the footnote below.)
So now how do you make sure that the scroll view has any idea where the nav bar is, so that (for instance) it doesnt't always position its content under the nav bar? The answer has nothing to do with layout guides. In the view controller, check the box "Adjusts Scroll View Insets" (or in code, automaticallyAdjustsScrollViewInsets). This will cause the view controller to automatically adjust the scroll view's contentInset property so that the scroll view positions its content appropriately.
This will work.
what's going on
So why is this the answer? And why is it so confusing?
Frankly, it's easy to get confused because the top and bottom layout guides are prominently presented to us as elements that convey layout information about translucent overlaid elements. However, they are not the only "translucency-aware" layout mechanism. They are directly relevant only for positioning of "normal" subviews, i.e., not the view controller's root view, and not content within a UIScrollView.
Content within a scroll view (or a subclass like UICollectionView and UITableView) will always be positioned in a more complicated way involving the scroll the view itself, affected by properties like contentInset, contentOffset, etc.. (Really, if scroll view layout were a straightforward thing, why would Apple have dedicated WWDC sessions to scroll view layout for the last four years running?!)
To summarize, as the steps above indicate, the three distinct translucency-aware mechanisms for managing layout are as follows:
Extends Edges determines if the view controller positions its root view so that it underlaps the nav bar.
Layout Guides provide a metric that tells where the "main" content area is, taking translucent bars into account. You can use these with Auto Layout to position normal views so they don't underlap. Or you can access the numerical values in code.
Scroll View Insets are the right way to ensure that a scroll view's content can underlap but doesn't always underlap. The automaticallyAdjustsScrollViewInsets property on the view controller can do this for you automatically in simple cases. (Presumably, this property just causes the view controller to update the scroll view's contentInset based on the same values it exposes via the layout guides. So if you needed to manage the insets yourself, that's how you would do it.)
fighting IB's layout guide mania
A footnote on "Fighting with IB":
Unfortunately, Interface Builder might fight you when you try to constrain the scroll view edge to its superview's edge. If you do a ctrl-drag from the scroll view to the superview, when it pops up the menu of possible constraints to add between those views, it might try to get you to constrain the scroll view against the view controller's layout guides. This is because IB mindlessly prefers layout guides to superview edges, when the superview is the root view. But when you're working with a scrollview, this is the wrong thing.
Why? For instance, suppose you accept a constraint against the layout guide. Then you will end up with a top constraint on your scrollview that constrains it to topLayoutGuide-64.0. That -64.0 is a hard-coded value compensating for the exact height of a nav bar. So what happens when one fine day the nav bar does not equal 64pt? Or when you simply turn off the nav bar entirely? Or want to re-use this scene in a context without a nav bar? Answer: then you get a broken layout.
So how do you force IB to add a constraint from the scroll view to its superview's edge, as opposed to the layout guide? As far as I can tell, the answer is that you can't add that constraint correctly in IB by doing a ctrl-drag between views.
Instead, you need to select the view, and then use the "Pin" control at the bottom of the canvas. This is the one that looks like a capital H with a box in its middle. In the top section of the Pin popup dialog, the section with the little diagram showing superview space constraints, you can use the dropdown controls next to the text fields to configure if the space constraint binds a layout guide or a superview. This is shown below:
Github link to demo projects: https://github.com/algal/ScrollViewUnderlapDemo
While algal's answer seems to have worked prior to iOS 9.0 it is unnecessarily complicated and broken beyond iOS 9.0. The easier way that also works beyond iOS 9.0 and requires no interaction with auto layout is to simply do the following:
Ensure Adjust Scroll View Insets is checked for the ViewController in Interface Builder (or set automaticallyAdjustsScrollViewInsets to true programmatically).
Set the class of the ViewController's root View to UIScrollView in Interface Builder (or replace it (self.view) manually with an UIScrollView in code).
While adding spacing constraints, Xcode does not show items which have negative distance with your view. It seems you added a vertical space constraint between UIScrollView and UIView. Delete that constraint, move your scroll view to below Top Layout Guide and add a new vertical space constraint between UIScrollView and Top Layout Guide.

Resources