UIScrollview won't scroll when Autolayout is used - ios

I have a scrollview which has two subviews (iPad). The view hierarchy is as follows:
-- UIScrollView
-- UIView1
-- UIView2
The frame of the UIScrollView is the size of the screen, the frame of UIView1 is also the size of the screen, but the frame of UIView2 is (0,0,768,2000).
The scrollview doesn't scroll vertically. According to the apple documentation, the scrollview should automatically set its content size. Can anyone help me out with this issue as why the content size is not being set properly ?
P:S: When I use a single view inside the scrollview and set a proper vertical constraint, it scrolls properly.

Scrollview won't scroll if you enable autolayouts. Technically when you scroll, all the elements in the scrollview change their position. So use auto layout if you are fixing the position of the elements in the scrollview.
Instead use a UIView as a container view inside a scrollview which contains all other objects like button , label, imageview etc. And then you will be able to scroll.
Check the below link for more details:
https://developer.apple.com/library/ios/technotes/tn2154/_index.html
In your problem try to put proper values of content size. Also check if the vertical scrolling is enabled or not.

The question is old, but the correct answer would be to make sure the autolayout constraints are all set.
Vertically, you should have some constraint pinning your View1 to the Scroll View Top, another one pinning your View2 to the Scroll View Bottom, and one third one setting the vertical space between View1 and View2. Also check that the views themselves (View1 and View2) have constraints for their heights.
Horizontally, pin one of the views to the Scroll View in both leading and trailing space, and the other view left and right to the first one (so they will have equal widths).
Once all of those are set, the content should scroll correctly.

Use contentSize property of scroll view in code. The best way is to use 'viewDidLayoutSubviews' method
(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
_scrollView.contentSize = CGSizeMake(568, 594);
}
2.Always make horizontal space >=0 between lowest of inner views and a scroll view. Automatically, auto layout make suggestions like '-160' and this negative space will not scroll.

If the Content size is more than the scroll view frame then only scroll view scrolls otherwise not .

Main Point : Mistake is in set 'contentSize' of 'UIScrollView', you need to set manually.
As seem in your Question
scroll view frame = screen frame,
view 1 frame = screen frame,
Its okay but
view 2 frame = (0,0,768,2000), then it overlapping on first view because your view2 x,y position is (0,0), so may be your first view will not display.
If you want to vertically add view 1 after view 2 then your view 2 frame should be
view2.frame = CGRectMake(0,view1.frame.origin.y + view1.frame.size.height , 768,2000);
And after added both of view then you need to manage contentSize of UIScrollView , in your case such like
scrollView.contentSize = CGSizeMake(768, view1.frame.origin.y + view1.frame.size.height + 2000)
I put simple logic, That may be helpful in your case:

How to enable scrollview scroll automatically when used with AutoLayout:
Please see the below link which help you to fix it correctly:
https://medium.com/#pradeep_chauhan/how-to-configure-a-uiscrollview-with-auto-layout-in-interface-builder-218dcb4022d7
Question for above help guide:
Which view is parent view?
scrollView or parent of scrollView?
Answer:
- Parent Of ScrollView (Give equal with and Equal height to view which is parent of scrollview)

Related

UIScrollView - Need Constraints for x position/width, Need Constraints for y position/height

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!

Not able to set ContainSize of my ScrollView through Storyboard

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.

Setting UIScrollView Width

I have a UIScrollView added to my ViewController. And a View on top of that Scrollview. I have done the following:
Placed scroll view inside my original View and set top, left, right, and bottom constraints. Unchecking Constrain to margins.
Added a UIView within the scrollView (to hold my labels and such) and added the top, left, right, and bottom constraints, constrain to margins unchecked. And set equal widths to the original View
I then add an image view and three labels inside the view placed within the scroll view. And add top, left, right, bottom, and height constraints for them.
The scroll view works and my view does scroll and my labels and image view are centered but everything is very wide.
I am wondering how I make it so the View is not wide and I cannot scroll horizontally, only vertically.
Add an equal-widths constraint between the view inside the scroll view, and the root-level view of the view controller.
I just recently figured this out. Try doing this:
Make a scroll view
Put all of your labels and buttons into a stack view (If you don't know about stack views, check this out: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/
Constrain the stack view's width and make sure the Allignment and Distribution are set to fill
Put the Stack View inside of the scroll view
Constrain the Scroll view to your hearts desire
Putting the labels and what you want in the scroll view should help with the width boundaries. Here's a picture of my successful scroll view. Hope this helps :)
In short, the contentsize is no effect while you use autolayout.
if you want you scrollview can scroll, uou should add a container inside scrollview and add origin subviews to the container.
For example, use snapkit (maybe some typos here):
you have a scrollview.set it's equal self.view's frame by autolayout
[import]then you add a containerView as scrollview's subview. set contraints:
make.edges.equalTo(scrollview) // mean its frame equal to scrollview
make.width.equalTo(self.view) // set width equal to self.view
make.height.equalTo(yourheight).priorityLow() // the actual height,if no changes,you can ingore .priorityLow()
add your sunviews to containerView,add the contraints must set to containerView,can't set to scrollview's.forexample,:
containerView.addSubView(myview)
myview.snp_makeConstraints { (make) -> Void in
make.left.equalTo(self.containerView)
make.top.equalTo(self.containerView)
make.right.equalTo(self.containerView)
make.height.equalTo(267)
}
Read this official doc -
Technical Note TN2154 UIScrollView And Autolayout.

How do I add UIView on UIScrollView

I wanted to add some labels and textfields on my view and that view should scroll, so I am thinking of putting view on scrollview.
I wanted to add some labels and textfields on my view
And that view should scroll
So I am thinking of putting scrollView
And then I wanted to put my view having labels and Textfields
Is it possible?
Please check scrollview property Bounces Vertically is checked or not if not check it
May be, your content is less, than ScrollView, that's why scrolling is disabled
Put view with labels in scrollview. Scrollview should be less in height than view. View should have height considering all ui cvontrols in it. should work like this
Make sure your scroll view height is not greater than view its content size has to be greater as all people says. You get confused between content size and scroll view height.
Meas using nib suppose your scroll view height is 300 and when you use the code content size should be greater than 480 so it will be scroll-able on iPhone 4 size device who's height is 480
To make sure your constraints are well defined, first check these steps:
Make sure your base view is a UIView
Put into a UIScrollView and add constraints to the edges of UIView
Put into the scrollview a UIView and add constraints to the edges of the scrollview. I call this "content view".
You should assign a width to the content view. I usually set the width of the content view equal to the width of the scrollview.
Put your labels/views/images/whatever into the content view and use autolayout constraints to resize them automatically to fit the target screen.
Please consider that:
Your scrollview must always have a height, fixed or dynamic. In order to avoid errors with autolayout, consider that:
the last element on the bottom of the content view must always have a constraint to the bottom edge of the scrollview, or
the content view must have a fixed height
If the height of your content view is less than the height of the scrollview, the view will not scroll. You should add more views or more margin to the bottom constraint of the content view.

UIScrollView content size fixed to 600x600(Main.storyboard size)

I've been facing this issue from past 2 weeks and not yet got a solution.
I'm using UIScrollview in my application where the problem exists.
Generally in my app, there is dynamic text and images with different sizes will come from webservices. For example, imagine the Facebook Newsfeed. My application is similar to the Facebook newsfeed. Sometimes, there will be only text, sometimes there will be text and images. And comments for that post.
As i've seen in many links, the heirrarchy i'm following is SuperView-->UIScrollView-->Content View and the elements are placed in that content view. I'm assigning the constraints from the elements in the contentview to the Superview (ContentView --- constraints -- SuperView). When the content in the view exceeds the size of the superview, it has to scroll. But the scrollview content size is limited to the size of 600x600 i.e., in main.storyboard, when we design for W any x H any size. I've seen many tutorials and searched many sites. But following them gives me no luck.
Any help is appreciable.
Here is how to set up a scrollView in Interface Builder from scratch that works with Auto Layout.
Start with a new ViewController. Drag out a scrollView such that it fills the view. Untick Constrain to margins and constrain the left, top, right, and bottom edges of this scrollView to the left, top, right, and bottom of its superview with offsets of 0. This allows the scollView to fill the screen on any device in any orientation. You can make your scrollView take up less of the screen if you like, just make sure it is fully contrained.
Add a view to your scrollView. This should be the only top level view on your scrollView and it will serve as your contentView.
Constrain the left, top, right, and bottom edges of this contentView to the left, top, right, and bottom of the scrollView with offsets of 0. At this point, you will see warnings about ambiguous content size. That is because you haven't told it yet how big your content view will be.
To size the contentView, add width and height constraints to the contentView. If you want it to scroll, the width and height must be larger than the width and height of the scrollView itself. If you only want to scroll vertically, set the width of the contentView to be equal to the width of the scrollView. To do this, in the Document Outline view, control-drag from the contentView to the scrollView and select Equal Widths from the pop up.
If you want to be able to change the height of your contentView from code (to account for dynamic content), first create a height constraint for your contentView by control-dragging within the contentView and selecting Height from the pop up. Create an IBOutlet to the height constraint by control-dragging from the height constraint (found in the Document Outline view) to your ViewController's code. Give the outlet a name like scrollViewHeight then set the height with a value like scrollViewHeight.constant = 2000 when you need to change the scrollView's height.
Simply add your UIScrollView to your UIViewController's view in the storyboard and add the appropriate constraints in the interface builder.
Then, build your content view in the code and give it any frame you want, now start adding your controls to this content view and calculate the size of each one (especially the height), and at the end you have the total height of your controls.
Now set the frame of the content view to match that height and add it as a sub view to your scroll view, then set the content size in the code like this:
_scrollView.contentSize = contentView.frame.size;
Another note, do this changes to the sizes in the viewDidLayoutSubviews to avoid any problems with different screen sizes but be careful, this event is called many times so have a BOOL or something to ensure that the code that creates the view and add it to the scroll view is executed once, e.g. like this
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
if (! built) {
// Do everything I explained above here
built = YES;
[self.view layoutSubviews];
}
}

Resources