When I first learned Autolayout, things where not too bad as you only had 1 width to cope with. I am struggling to get a Scrollview to grow depending on device (width) and its content equally. The scrollview has paging on so a StackView is not possible I believe.
The current issue is the first view grows to the right width (I believe its down to the centerX), however the overall content size of the scrollview is not large enough (iPhone 6) and the secondView is only 320 wide.
I could do this in code but I am sure you don't need to.
I have tried quite a few options like saying greater than on the width
As i understood your question, you want autoresize for views inside scrollview. So, instead of creating width constraint, you should add 'equal width constraint' to your target view:
second step
if scrollview tells you, that it has ambiguous scrollable content, add bottom constraint for it.
Basically, if you need autolayout inside scroll view, you should provide contentView and setup it with trailing, leading, top, bottom contstaint to scroll view:
This trick allow you to add another object inside scrollview and use autolayout easily.
Hope this helps
Related
I try to auto-resize my view with auto-layout contraints, but I have some errors of Y-position missing. I can't understand what is wrong, I attached my Y-position to the top of the view.
Thanks for your help, here is the screenshot:
The problem is that you don't set a fixed height but, if you can, ALWAYS AVOID to put a fixed height for a view. For an app that can fit all screen is better to use different techniques.
If don't want to set a fixed height on your view, you have two possible options:
Give to the view a bottom constraint. You should also set the distance between the bottom of your view and the screen (or another object below your view).
Use stackview. If you place your views into a stack view you will be able to autoresize the width and height of your views according to the screen dimension.
You must give a height for the view or construct it's subviews in a way that gives it a height by hooking constraints properly from top to bottom
when you have a y position error it means top, bottom and height issue
and when x it means leading , trailing and width issue
IF you want to create dynamic view drag a vertical UIStackView and give it a height and in runtime add items to it
self.myStackView.addArrangedSubview(lbl)
I have a view hierarchy that looks like this (based on other answers and Apple's advanced AutoLayout guide for working with UIScrollView):
The 2 steps required for ScrollView are:
Set up constraints for position and size (frame) of ScrollView: The same way you do it with any other view.
Set up constraints for content size: By making sure that there are constraints from the ScrollView's subviews touching all edges (leading, trailing, top, bottom) of the ScrollView, if you're doing this in interface builder and not programmatically.
Step 1 worked fine at first and this was the result:
No problems with position and size as expected. I just need to define the content size (content height and content width) now in Interface Builder with Step 2.
Now I add the constraints touching all 4 edges of the ScrollView like so:
Suddenly, the ScrollView doesn't know it's position and size (frame) anymore.
I've looked at other answers and followed the various steps, but can't seem to resolve this issue. Sorry I'm not able to post Storyboard screenshots because of privacy issues
Set the scroll view's top, bottom, leading, trailing constraints to its superview to 0.
Set the view that is inside the scroll view and set its top, bottom, leading, trailing constraints to its superview to 0.
Select the view that is inside the scroll view, go to the size inspector and set the "Intrinsic size" to "Placeholder".
Scroll views can be a little tricky at first. You really have 3 parts:
Actual frame of the scroll view
Actual frame of the subview(s) contained in the scroll view
The contentSize of the scroll view - that is, how far it should scroll in either direction
So, 1. is pretty straight-forward.
The second part also seems straight-forward, except that we tend to "pin" subviews to the inside edges of their superviews. In the case of scroll view subviews, those constraints are what defines the contentSize. You also have to make sure the subviews have a "size".
Starting with just one subview, you would:
set the scroll view's constraints as "normal".
set the size of the subview - just for demo purposes, set it to 100 x 100
pin all four edges of the subview to the four edges of the scroll view
Run the app. Assuming you set background colors so you know what you're looking at, you should see the scroll view positioned and sized as you'd expect... you should see the subview of 100 x 100 sitting somewhere inside the scroll view... and you will likely not be able to do any actual scrolling.
If you go back and change the subview to, say, 100 x 800, and still have its bottom constraint pinned to the bottom of the scroll view (the subview's superview), and run the app again... You should be able to scroll up and down for the full 800 pt height of the subview.
The way to think about it is: the scroll view's content - whether it's one or many subviews - has to define its own size, which will define the scrollable area (the scroll view's contentSize).
Hope that makes sense!
I am adding more than 8-9 controls in my ScrollView but I am not able to set ContaintSize of that ScrollView so that I can able to scroll and view all controlls.
I HAVE SET below constrains to my scrollview and add some controls into my scroll view with the help of contain view.
Scrollview.top respect to his superview
Scrollview.bottom respect to his superview
Scrollview.leading respect to his superview
Scrollview.trailling reapect to his superview
Than I have added UIView as contain view and set all constrain respect to scrollview.
Than added all controls into view but still its not scrolling as expected.
By below code I am able to set containview but its ststic one and cant assume that 1000 is my contanent height.
Scrollview.contentsize = CGSizeMake (Scrollview.frame.size.width,1000);
Above part is static as I have many lable with multiple line in it.
All data is dynamic comes from server si cant set it static.
Can any one help me out how to set autolayout of scrollview so I can get dynamic content size?
Edit: some time I am getting autolayout error into storyboard like below.
Scrollview has ambiguous scrollable content height
An while i reslove conflicts its not showing proper scrollview in my screen.
Faced the same issue recently. I'm sure that you did your research but here is the guide I used, nonetheless.
https://www.natashatherobot.com/ios-autolayout-scrollview/
Also if you have many labels it would be good consider using a 'UITableView' or a 'UIStackView'.
Edit
Make sure you center the scroll view vertically and horizontally in respect to its container.
You have to define constraints for the scroll view like this..
ScrollView :
top ,left , bottom, right pinned to superview.
ContainerView:
top, left , bottom , right pinned to scroll view
width pinned to main view
And make sure that every subview inside the container view should have constraints in such a way that it should define the height of container view.
As i understand your issue you forgot to set the height constraint of your contentView, just try by setting it.
No need to set the fix height of scrollView's contentSize, please see the below code.
self.scrollview.contentSize = CGSizeMake(self.contentView.frame.size.width, contentView.frame.origin.y + contentView.frame.size.height + 10);
Note: you need to add height and width constraint of contentView if you need scroll according to it.
I am creating a UIScrollView from xib, in which 3 view are there 2 UIViews and in middle an UIImageView. when I am setting constraints Xcode asked to set Y position constrains. But the problem is Y position constraint is blocking Scrollview to scroll down and automatically adjusting the views which looks ugly in landscape mode.
when I am delete that constraint it ask to fix height of subview. I searched a lot but I am new in autolayout so not understanding many of solutions. any help would be great.
You have to set all the height constraints in the content view.
But you also want the height of the Content to be proportional to the screen size.
To do this assign the height constraint of the imageview [equal|proportional|a-computation-of] to the view containing the UISCrollView.
It seems weird to skip levels of herarchy when assigning constraints between two views whose are not direct ancestor/sibling of each other but within a scrollview (at least) it is perfectly acceptable.
You are basically telling the scrollview that it's content has a known size and at same time setting this content to adapt dinamically to the screen size (if the constraints of the root uiview are set correctly)
UIView1
|---UIScrollView
|---UIView2
|---UIImageView [heightConstr.constant=UIView1.height-UIView2.height-UIView3.height-margins]
|---UIView3
This is the basic idea, to be done programmatically, then you can explore other solutions.
Unfortunately the constraint system in ios pretty much sucks when it's up to more complex equations involving more views for a single constraint.
UIScrollViewcan be tricky when adding constraints. You should always add a subView that will behave as the content view for your UIScrollView and all your subsequent views will go inside this content view.
UIView1
|---UIScrollView
|---UIContentView
|---UIView2
|---UIImageView
Set your UIScrollViewconstraints as you would normally but set your content view to have leading, trailing, top and bottom to the UIScrollView but also add two more constraints which will be equal width and equal height to the viewController.view but will have a low priority (So that whichever direction your content will increase in, that constraint will break and automatically increase the content size of the scroll view by taking in the inferred height of the content view). Now go on and add constraints on all your subview as you normally would. Which i'm assuming would be:
Your topmost view will have top and leading and trailing to its superView and also a fixed height.
Your bottom view will have leading, trailing and bottom to its superView and also a fixed height.
Your UIImageViewwill have a leading, trailing and top to top most view and bottom to the bottom view.
Edit:
Here is the screenshot just in case (To show the view hierarchy with the content view's constraints in the inspector)
I have:
application, that should work in landscape and portrait mode.
view with full-size scroll view on top.
some view inside scroll view with fixed width and height. (with added H and W constraints)
set to view inside scroll view as horizontal centered in container. (added according constraint)
I have warning in interface builder "Has ambiguous scrollable content width".
The only way to fix this problem, that I know - is set trailing and leading constraints.
But for different iPhones (5.5", 4.7", 4") I need to set different trailing and leading constraints.
How can I eliminate this warning and still have centered horizontally view with fixed W and H for all iPhone sizes?
I create Github repo to illustrate this problem: ScrollViewAmbigous
This is not duplicate of UIScrollView Scrollable Content Size Ambiguity
, but it similar (and not answered although), but this question especially related to different sizes of iPhones.
In the morning with a fresh cup of coffee I figured out workaround for this issue!
So, here is the initial state for simplest case:
scrollView with 0 constraints to all edges
Button centered Horizontal and Vertical with fixed Width and Height
And, of course Has ambiguous scrollable content width and Has ambiguous scrollable content height annoying warnings.
All, that we have to do is:
Add 2 additional constraints, for example "0" for trailing and/or bottom space for our view (in my case - UIButton)
Important: you have to add trailing and/or bottom constraints. Not "leading and top" - it's not works!
You can check it in my example project, that demonstrating how to fix this issue: ScrollViewAmbigous
P.S.
I don't know why it works and how Xcode detect which constraint is more prioritised (because I'm not set priority for these constraints explicity), but I'll be thankful if someone explain, why it works in comments below.
Problem :
The warning is telling us that the the content size of the
scrollview depends on its subviews.
while your subview don't have any strict rule of position and size (no fixed constraints) it will confuse nib generated scrollview
content size.
Solution :
Make only one subview as a 'contentView' for scrollview.
Add strict (fixed) constraints to that 'contentView'.
Best practice : equal width and height to its scroll view.
Add all other subviews and constraints to your 'contentView'.
There seems to be a lot of confusion on this issue. My take is that a UIScrollView must have TWO trailing space constraints, an 'inner' one connecting it to one of it's subviews (so it can know its content width), and another 'outer' one connecting it to a sibling or superview so it knows its frame width.
Same principle applies for height, i.e. two bottom space constraints.