Using UIScrollView with Autolayout - ios

I am trying to get a simple scroll view to work with autolayout. My SuperView has a Scroll View. Inside the Scroll View is a ContentView and then a ButtonsView.
View (320x480)
|
|__Scroll View(320x480)
|
|__ContentView(320x556)
|
|__ButtonsView(320x175)
The ScrollView constraints to the SuperView are 0,0,0,0 for Leading, Trailing, Bottom and Top. The ContentView constraints to the Scroll View are 0,0,-96,0 for Leading, Trailing, Bottom and Top. The -96 is because my content view height is 556. I have a ButtonsView inside the ContentView. The ButtonView constraints to the ContentView are 0,0,238,64.35 for Leading, Trailing, Top and Aspect Ratio.
I am getting Missing Constraints and Scrollable Content Size Ambiguity errors on my xib.
I do not want to to hardcode the width and height for either my ContentView or ButtonsView as I want the xib to work for iPad as well.
Can someone please tell me what I am doing wrong and how I can get this fixed?
Thanks
This is not a duplicate question. The question above has a scrollview which doesnt work as intended. My question is more about how autolayout rules can be applied to the scrollviews.

You should let the inner contents of your ScrollView to determine its content size. Whether by indicating fixed height and width (which you don't prefer). Or by putting constraints to determine the sizes of inner contents related to the View. So in your specific case, you can add an Equal Widths Constraint for ContentView and View. To adjust height, you can add an Equal Heights Constraint for ButtonsView and ContentView with multiplier of 175/556

You just need to add a Bottom constraint in your ButtonsView to the ContentView. With those constraints, now the ContentView can guess its height, and so the ScrollView, too.

Related

How can I center items horizontally inside uistackview

I have a UIScrollView and an UIStackView. I want to add elements from top to bottom and let the scrollview scroll only vertically. I have trouble with this and don't really get what the problem is.
So I added the constrains that the UIScrollView should stick to the super view on all sides, added the stackview, you can see its constrain on the pic, also added a label with fixed width. I want this label to be center in the scrollview without the scrollview starting to scroll horizontally.
I think Im missing some constrains? The scroll view also says it has "ambiguous scrollable content width".
First to fix ambiguous you should create a contentView for the scrollView as Apple recommends and give it width of outmost view then put the stackView inside it and Change alignment of the stackview to .center + alignment of the label itself
Scrollview // pinned to top , leading , trailing ,bottom
contentView // pinned to top , leading , trailing ,bottom , and have width = outmost view (very important)
stackView

UIScrollView Autolayout height not setting on dynamic content

I have two labels that are inside a stack view that is encapsulated in a scroll view. The layout structure is like the following:
The layout looks like so in the interface builder. (This is the view with the contentView selected)
The Content Stack View is pinned to the contentView's via top, leading, trailing with 8pt on each.
The labels are set at runtime and can be quite tall. This cuts off the text and causes the scroll view to not be scrollable. (Cuts off at bottom)
I've went through a few other similar questions on here but was unable to find a solution to mine.
Some are resources I went through I looked at were Mokagio, and Natasha.
I have been on this for over a day now and am completely stumped.
How does the Scroll View's content size become scrollable from the generated content?
Please follow below steps:
Add UIView into UIScrollView and then add both UILabel into UIView.
Set top, bottom, leading, trailing constraints to UIScrollView and UIView
For both UILabel set top, leading, trailing, bottom, width, and height constraints.
lastly edit height constraints to set - priority High(750), select >= from constants dropdown for both UILabel
IMPORTANT: set UILabel's number of lines to 0
Please see below screenshot for UIlabel constraints:

UIScrollView height while adding content programmatically in UIStackView

I am trying to make a view containing an UIScrollView. This UIScrollView contains 3 UIViews. The last one contains another UIStackView I wanted to fill at runtime.
Here an image of the storyboard :
But when I add content at runtime in the second UIStackView, the ScrollView's height remains the same.
The second UIStackView is defined as the first one with:
Axis : vertical
Alignment : Fill
Distribution : Equal Spacing
Then I use :
mStackView.addArrangedSubview(matProgress)
The result below :
What's the way to have the bottom view and the ScrollView stretch to fit the content.
The layout can be done with auto-layout and constraints.
The key points are:
do not set height constraints on either StackView
set the "Main" StackView Distribution to Equal Spacing
set the "Main" StackView Leading, Trailing, Top and Bottom constraints to its Superview (which is the ScrollView)
you do need to also set a width constraint on the "Main" StackView to control the horizontal contentSize
The only quirk will be on startup. If you have NO content in the bottom / inner StackView, it will still "exist" in the Main StackView and take up space. There is a trick to get around that, but it must be done in code.
You can see a working example here: https://github.com/DonMag/StackyScrolly
If you have UIScrollView and the child views with auto-layout. Setting programmatically the height of the scrollview will stretch the inside views to comply with the auto-layout.
So, you get by code the height of the third view and set the UIScrollView height to view1.height + view2.height + expectedThirdViewHeight.

How do you set constraints for scrollview that doesn't occupy the whole parent view

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.

Disable Horizontal Scrolling of UIScrollView AutoLayout Resizable ScrollView

I have a UIScrollView which is getting resized on runtime according to some conditions. Now i used auto layout properly without using a single constraint extra or less. The first subview of scroll view has leading, trailing, top, bottom and equal width to scroll view and the height of the content view is managed by its inner content which is also changing depending on the runtime condition. Now according to my constraints my content view should not scroll horizontally as i used equal width to scrollview. But its happening. Can anyone suggest what am doing wrong? Here is the images of constraints i have used.
NOTE:- I have seen the posts on stack where this kind of question answered but my case is different.
Content UIView width should be equal to the width of UIScrollView's superview for instance, not UIScrollView itself.
In my case, I used to 'constraint to margin' option while I am adding constraint from storyboard. When I only add trailing and leading without relative to margin problem solved. I did not give any superview to my UIScrollView.

Resources