I am trying to layout my detail screen in IB with a tab bar and nav bar. However, there are three issues with the display when the simulator runs:
There is a gap at the top of the screen,
The dynamic label content extends past their container views at the bottom
The scrollbar doesn't reach to the bottom of the content.
Screenshot of simulator displaying the issues described
My question is how should I set my constraints so that the above issues are resolved?
I have a lot of constraints and I'm not sure where I'm going wrong or what would be the best way to present the steps I've taken so far. But here is a screenshot of my constraints and here is a summary of the constraints/steps I've taken so far:
Main view contains just one child: The Scroll View. Scroll view is pinned to top, leading, trailing of main view and bottom is pinned to the Bottom Layout Guide.top,
Scroll view has just 1 child subview ("Content View"). Content View is pinned to top + 64, leading, trailing, bottoms to Super View, and it has equal heights and widths to the Main view.
The content view has an image, Recipe Title subview, and Shadow Background subview. The Shadow Background subview contains another subview with some labels of dynamic height. I have constraints to pin the leading and trailing sides of these containers to the superview. And I have top, bottom, leading, trailing constraints to pin these subviews to the superview and/or eachother so that there is a chain from top to bottom.
The Shadow Background View contains the labels of dynamic height. The labels also have pin constraints of top, leading, trailing and bottom with the exception of the last label which does not have the bottom constraint.
I do not have any code that updates the layout-- everything so far is in the IB.
Any help is GREATLY appreciated!
Hallelujah! After spending a full frustrating week, I've finally found the magical formula in IB for laying out a scroll view + navbar + tab bar + dynamic label height.
My original problems were caused by the following mistakes:
Adjust Scroll View Insets should have been set to false
Content View Top and Bottom pins were incorrect
Missing some heights on some of the subviews
Last subview wasn't pinned correctly on the bottom
Maybe not all these steps are required and maybe this isn't the most perfect solution, but this is what worked for me. Here is a diagram of the solution for those that prefer pictures.
Main View -> Attributes Inspector -> Uncheck the Adjust Scroll View Insets checkbox.
Add Scroll View. This is the only child of the Main View. Pin Top, Leading, Trailing Space to the Main View. Pin the Bottom to the Bottom Layout Guide.
Add one subview (name it "Content View"). This is the only child of the Scroll View. Pin Top, Leading, Trailing Space to Scroll View. Pin Bottom to Scroll view with a constant of -49 to account for the tab bar. Also set its Height and Width to be equal to the Main View.
Add a child subview to the Content View. Top is pinned to Superview with a constant of 62 to account for the Nav Bar. Leading and Trailing is pinned to the Superview. The view also needs a Height-- give it either a fixed value or a minimum value if it is dynamic content (ex: Height >- 20). You may also need to give the Height constraints a lower priority such as 250.
Continue adding sibling subviews as needed. Pin the tops to the previous sibling subview. Pin the Leading and Trailing to the Superview. The last sibling subview should be pinned to the Superview. Each subview needs a height. There needs to be one continuous chain of constraints (Top & Bottom pins, Height) from the top subview through to the bottom in order to avoid that "Scroll View has ambiguous scrollable content height" warning and have the scroll work correctly.
Do a happy dance.
Hope this helps someone else.
Make the content view's top constraint have a constant of 0, not 64. For the label extending beyond the bottom of the container view, you'll have to post more information about the layout for us to help.
Related
I am unable to get a scrollview to scroll if I use a view in the scroll view. I followed the example https://useyourloaf.com/blog/scroll-view-layouts-with-interface-builder/ , which used a stacked view in a scroll view. When I follow this example and use a stack view, it works. My UI requires a view because of the layout I need for the controls.
I have a sample project at: https://github.com/eloew/ScrollViewTest which illustrates the problem. I have used the storyboard so no code to post here.
Is it possible to use a view in a scrollview?
#eloew You are almost done. You just need to adjust few things.
Your view width have to equal with scrollView width.
Put the height and bottom constant of Second textField/Label.
Done
The procedure you are using is correct but it is sometimes tricky to setup constraints. Your view needs to have either implicit or explicit width and height. Then it needs to be inserted into scroll view and have all 4 border constraints setup.
Looking at your project you have missed a few constraints. To debug a view like that it is easiest to first set it up outside the scroll view. Take your view outside it and setup leading and top constraints to it's superview. Now modify your constraints until you see a desired result.
For your specific case I used:
View width equals to superview width
First label leading and top are pinned to superview leading and top
First text field leading to First label trailing
First text field trailing to Superview trailing
First text field center vertically to First label
Outlet label leading to Superview
Outlet label trailing to Superview
Outlet label top to First label bottom
Second label leading to Superview leading
Second label top to Outlet label bottom
Second text field leading to Second label trailing
Second text field trailing to Superview trailing
Second text field center vertically to Second label
Second label bottom to Superview bottom
After all these are set I have a nicely layout view without a scroll view. There should be no errors visible.
Now add a scroll view. Pin it to leading, trailing, top and bottom. Then drag your view inside your scroll view and this view to scrollview leading, trailing, top and bottom and set equal width between your view and your scrollview. That should be it.
Short answer is yes it is possible. Simply add a view as a subview in your scroll view and set its constraints.
Apple's documentation
It is simple enough task, you can even find examples here on SO.
I've been trying to create a UIScrollView for user registry but with no success. I'm using auto layout and all of the fields that go inside the scroll view are static. Because of the usual ambiguous height issue, I've added a UIView inside the scroll view, set the constraints to the margins of the scroll view and centered aligned it. After that I added all of the fields inside that Content View, in the storyboard.
The content fields have their constraints setup as you would expect, but when I get to the lowest field and set the bottom constraint to the bottom of the Content View then everything breaks.
I'm asked by Xcode to set the priority of some views, and when I do as is says, the Content View size stays the same and the views are shrunken.
I tried not to put the last bottom constraint and resize the Content View by code but the height is not resized as is should.
I'm looking for a good solution to do this in storyboards and auto layout.
Update: I added a bottom constraint with a low priority, but the content scroll view is not expanding to show all of the fields.
Add&Set ScrollView(UIScrollView)
Add&Set ContentView(UIView) with subviews
! Set ContentView Width equal to View Width
Set all subviews constraints
View1 should be tied to the top of the ContentView
View4 should be tied to the bottom of the ContentView
All SubView (View1, View2, View3, View4 ...) must have a height and distance between each other
P.s. In your case, if iOS > 9.0 you can replace ContentView with UIStackView
You are using auto layout so the size of the content view is determined by constraints. Follow the below steps to provide proper constraints:
Drag the Scroll View inside main view and provide constraints Top, Bottom, Leading and Trailing in align with Super View (Main View) as
per screenshot.
Take View which will contain your content and drag inside Scroll View. and provide the constraints Center X, Center Y, Top, Bottom,
Leading and Trailing in align with Scroll View as per screenshot
Put all the element inside content view which is a subview of scroll view and provide Top constraint relative to the element above
it, to make equal space between the elements (eg. label, button etc.)
(Make sure you provide required constraint for X-position)
Last element is "Register Account" button make sure you provide the Top Constraint relative to country and Bottom constraint relative to
superview (content view) and change the priority for Top or Bottom
constraint as per screenshot, otherwise it gives error.
I'm trying to build UI similar to that of ios photo gallery : Navigation view controller with a scrollview occupying 80% height and 100% width of the parent's view and the collection view controller occupying the rest of the height and 100% width. So here's how it looks like :
The blue area is scrollview and its content view. The bottom part is a collection view which suppose to behave like a carousel. You can see the constraints that I have set in the following screenshot :
:
I want to set the scrollview height so that it only occupies 80% of the parent view estate and the collection view occupies the rest. However, I can't seem to resolve scrollview constraint issues such as autolayout not able to resolve height/y position of scrollview. As you can see in the above pic, I tried setting the height of the scrollview to 50% of the parent view but the autolayout still complains about not being able to resolve height. If I let interface builder resolve the issue, it just adds spacing to the content view inside scrollview and pushes it down as a result. You can see that in the following screenshots.
Your view heirarchy is correctly setup so thats quite nice and you are on the right track of what constraints to add. I'm going to write all the constraints starting from step 1.
To your UIScrollView add a top, leading and trailing constraint to the superView. Also add a equal height constraint between your UIScrollView and the superView and set the multiplier to 0.8.
Now add your UICollectionView below the UIScrollView and give it a leading, trailing and bottom to the superView. Also add a vertical spacing between the UICollectionView and UIScrollView.
Now add for the contentView inside the UIScrollView. Add a leading, top, bottom and trailing for the contentView to UIScrollView. As soon as you do this, the constraints will break and Xcode will complain. Now what you need to do more is add a equal height and width constraint between the UIScrollView and contentView. Set the priority of this equal height constraint (assuming you want vertical scroll) to something like 250, so that it breaks when the content inside the UIScrollView becomes too large to be displayed completely.
Now as far as that extra spacing issue is concerned. What you need to do is, select the UIViewController that has your UIScrollVIew and then select the attributes inspector for this UIViewController and uncheck the adjust scroll view insets option. For a screenshot, check this.
As i see from above do the following.
Add leading, trailing and top constraint to scrollview.
Add height constraint i.e drag from scrollview to superview and add equal width, in equal width constraint change the multiple factor to 0.8.
Add leading trailing, bottom constraint to collection view with respect to superview and vertical space constraint with respect to scrollview.
Using Xcode to create a new project, a Tabbed Application.
On the first view controller I add a UIScrollView, bind it to the view for all borders. Then I add a UIView "Content View" with equal width as the superview of the UIScrollView. I add a label on the top and a label on the bottom of the content view, and make sure that the size of the content view amounts to a higher height than the height of the scroll view, so that we get a scroll.
Still I get a horizontal scroll bar in the view. Why? The width of the content view is bound to the width of the superview of the scroll view, which should thus be as wide as the device, and give no scroll. What am I missing?
The project is downloadable from here if you want to play with it.
Your problem is that you have two constraints for the ScrollView which are set relative to the margin.
If you make the leading and trailing constraints relative to the superview with no margin then your code works as you require with no horizontal scroll bar.
I have a view controller with a scrollview.
The scrollview has a sub View (content view) which is a view I have copied from another VC. I cannot get the scroll to work, I have tried:
Set constraints of scrollview against the container (pinned top/bottom/sides =0)
Setting Horziontal and vertical spacing of Content view against the scrollview which also didn't work
Set the content view to superview Leading/Trailing space to container margin, Top space to top layout guide and Bottom Space to bottom layout guide - still no scroll
Have also tried to set the scrollview size in viewdidload :
scrollView.scrollEnabled = true;
scrollView.contentSize = contentView.frame.size;
And no scroll.
I am possibly missing something basic here but although have tried numerous tutorials on line I can't get my head around using scrollview.
Pop up when dragging content view to scroll view
Your content view is not embedded in your scroll view.
to Scroll UIScrollView you need following Steps
pin UIScrollView with its SuperView from all four side Top, Left, Bottom, Right
Add a contentView (UIView) in ScrollView and pin it with UIScrollView with 0 margin from all four sides. also add equal width constraint.
add subviews to contentView make sure all view pinned with constraint from top bottom & also add Height Constraint for subviews.
no need to set any property or content size in code.