iOS - UIScrollView not scrolling, though scroll bar is shown - ios

I have a Scroll View, and inside it a UIView called "Content View", that contains all of my elements.
The Content view is equal to the Scroll view's top, bottom, leading and trailing. Also equal its width & height.
I also added self.scrollView.contentSize = self.contentView.frame.size
in ViewDidLoad.
When I scroll I can see a scroll bar going up and down on the side, and it seems like the page length is correct according to the bar, but the content itself does not scroll as you can see here:
What am I doing wrong?
Thanks!

I ran into this issue (or something very similar) where the scrollbar would scroll, but the content did not. It drove me crazy for a while because it seemed like everything inside of the scrollview was constrained correctly in Interface Builder. Finally, I noticed that the top item within the scrollview container (container = the view inside of the UIScrollView that contained all of my views) was constrained to the top by aligning with a view outside of the scrollview.
Once I removed the constraint that was aligning the top with an external view from the ScrollView and instead aligned it with the main container within the UIScrollView, everything worked fine. Hopefully that helps in case someone runs into this issue and the other mentioned solutions don't fix it.

The Content view is equal to the Scroll view's top, bottom, leading
and trailing. Also equal its width & height.
You need to remove the width and height constraints. Top, bottom, leading and trailing should stay. Also, remove that contentSize setting from viewDidLoad.
I assume you want vertical scroll. In that case, you should set contentView's width constraint to be equal to View's width (not scrollView's but View's which is the root of the hierarchy).
That should do the trick, assuming that vertical constraints of contentView's children are properly set up.

By default Content Layout Guides is enabled for a Scroll View. So when we pin the content view (main view inside the scroll view) on all 4 sides and equal width and equal height (with lower priority), it takes Frame Layout Guide for top constraint, this is the root cause of the issue where only scroll indicator moves and not the entire content.
You can uncheck Content Layout Guides from Scroll View Size Inspector. Or if you want to use it change the top constraint to Content Layout Guide instead of Frame Guide Layout and it worked as charm. Please refer below screenshot.

The 1st thing I had to do is what user3199693 said: remove that line from viewDidLoad (that made the wrong scroll bar I saw to go away). Also I set contentView's width constraint to be equal to top View's width, as he said.
That was good, but still didn't solve the problem. What did help was equal the height of the content view with top view.
Got the idea from here.

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.

dynamic height of of scrollview subviews in autolayout ios

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)

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.

UIScrollview is not scrolling beyond UIView height even though UIView frame is increased

I am trying to create a screen where scrolling is required in iphone 3.5 inch screen . I have attached images which contain the configuration of uiviewcontroller , uiscrollview , uiview . The problem is eventhough the height seems to increase , when i run iPhone 4s , some part of scroll is hidden beyond the UIView (Although uiview height shows 700 when i print the height in console) . What might be the problem ? Please help me ?
You have constraints that have negative values. On the last screenshot, which I assume are the constraints from the view inside the scrollView, the bottom offset to the superview is -400.
I think this is why you don't see the entire view because the bottom offset is negative. Try setting this value to 0, this should fix it.
If this does not fix your problem, maybe you could specify for which view the constraints from the images are.
Let me know how it goes! Good luck!
When you work with UIScrollView and AutoLayout it's always tricky.
You have to add all your subviews to one UIView and add that view to UIScrollView.
Autolayout Constraints you need:
For UIScrollView:
Left to Superview
Right to Superview
Top to Superview
Right to superview
For Inner View of UIScrollView (i.e The only view inside ScrollView):
Width & Heigh
Left, Right, Top and Bottom constraint to Superview (i.e. ScrollView)
Also add Horizontal Centre to Superview.
And it'll work like charm (Works every time for me at least:)
The contentSize must be larger than the scrollview's frame for there to be anything to scroll. :)
In this case, they're both (600, 1300) so change your scrollView's height to (320,480)
It's a bit confusing, but as Yuvrajsinh told you, you need to set the auto layout constraints for your scroll view to its 4 sides to the superview. Then do the same with the content of the scrollView, and the most important: Set a fixed/not related with scrollview height and width for the content
Thanks for the information and suggestions . Now it is working correctly . What i did is
set scroll view top ,left , right , bottom aligned to superview
Set content view of scroll view to top , left , right , bottom aligned to scrollview
set the content view of the scroll view to "Equal Heights" and "Equal widths" to the top superview.
Then i set the equal height constraint to have low priority of 250
Now i can scroll whenever required based on the size of the phone screen :)

Resources