UIScrollView not scrolling regardless of large contentSize
Asked Answered
S

5

11

I have created a UIScrollView and added subviews to it in Interface Builder, but I am not able to get it to scroll. I have looked at other similar questions, but I have set my contentSize appropriately. In fact, I have even tried setting incredibly large contentSize and it fails to make a difference. What am I missing? Note that the UIScrollView is an IBOutlet:

@property (strong, nonatomic) IBOutlet UIScrollView *scroll;

This is in my viewDidLoad:

self.scroll.scrollEnabled = YES;
[self.scroll setContentSize: CGSizeMake(2400,8000)];

Here are screenshots from Interface Builder:

view heirarchy

scrollview and its subviews in interface builder

referencing outlet

Here is the view while running, but any attempt at horizontal or vertical scrolling at any point does not work.

screen while running

Saffian answered 22/1, 2014 at 3:24 Comment(13)
Have you linked IBOutlet to the storyboard yet?Maxwell
I believe so. I have added a screenshot of the referencing outlet. I have also tried self.scroll.backgroundColor = [UIColor redColor]; and it works fine, so I believe everything is linked properly.Saffian
could you please set frame before setting setContentSize? just for a try.Laclair
What should I set the frame to?Saffian
anything less than your ContentSize.Laclair
I have tried self.scroll.frame = [UIScreen mainScreen].bounds; before setting contentSize and it has not made a difference.Saffian
are you using autolayout.?Lotic
I am not sure what that. I did not explicitly use it, but maybe indirectly. I simply dragged labels, buttons, text fields, and a date picker into the scroll view in Interface Builder and aligned some of them using the guides.Saffian
Could it have something to do with the fact that it is nested under a navigation controller? I began with the Master-Detail template and this is inside the DetailViewController.Saffian
In your interface builder, select ViewController then file inspector and in interface builder document section you can see Use Autolayout checked or not. If its checked, then remove check and try.Lotic
Indeed it was checked, and unchecking it worked! Could you please provide that as an answer with an explanation of what enabling/disabling AutoLayout does and why it was causing a problem? Thank you very much!Saffian
You should also make sure that you add the scrollview as a subview to your main view.Nemato
Possible duplicate of UIScrollView not scrollingGorse
Z
23

Turning Auto Layout off works, but that's not the solution. If you really need Auto Layout, then use it, if you don't need it, turn it off. But that is not the correct fix for this solution.

UIScrollView works differently with other views in Auto Layout. Here is Apple's release note on Auto Layout, I've copied the interesting bit (emphasis mine, at third bullet point):

Here are some notes regarding Auto Layout support for UIScrollView:

  • In general, Auto Layout considers the top, left, bottom, and right edges of a view to be the visible edges. That is, if you pin a view to the left edge of its superview, you’re really pinning it to the minimum x-value of the superview’s bounds. Changing the bounds origin of the superview does not change the position of the view.
  • The UIScrollView class scrolls its content by changing the origin of its bounds. To make this work with Auto Layout, the top, left, bottom, and right edges within a scroll view now mean the edges of its content view.
  • The constraints on the subviews of the scroll view must result in a size to fill, which is then interpreted as the content size of the scroll view. (This should not be confused with the intrinsicContentSize method used for Auto Layout.) To size the scroll view’s frame with Auto Layout, constraints must either be explicit regarding the width and height of the scroll view, or the edges of the scroll view must be tied to views outside of its subtree.
  • Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints between the view and a view outside the scroll view’s subtree, such as the scroll view’s superview.

Apple then goes on to show example of how to correctly use UIScrollView with Auto Layout.

As a general rule, one of the easiest fix is to create a constraint between the element to the bottom of the UIScrollView. So in the element that you want to be at the bottom of the UIScrollView, create this bottom space constraint:

enter image description here

Once again, if you do not want to use Auto Layout, then turn it off. You can then set the contentSize the usual way. But what you should understand is that this is an intended behaviour of Auto Layout.

Zanze answered 22/1, 2014 at 4:18 Comment(3)
I am still confused as to why it was not scrolling previously, but I understand how the "Pure Auto Layout" approach works, so I think I will use that instead of simply disabling Auto Layout. Thank you very much!Saffian
My guess is that previously there isn't any constraints to say "the content needs to be at least this much!", and the compiler is ignoring your setContentSize: call because it's just looking at your constraints to see how much content there is in the scroll view.Zanze
I had a very similar problem. I was trying to create a scroll view of text fields that grow and scroll to remain on the screen. Setting the bottom constraint solved my problem!Fichu
L
2

Try turning off autolayot by

Select ViewController then file inspector and in interface builder document section you can see Use Autolayout checked or not. If its checked, then uncheck it.

This info UIScrollView And Autolayout may give the details.

Lotic answered 22/1, 2014 at 4:4 Comment(1)
Thank you, this solved the scrolling problem, but as @EnricoSusatyo said, it seems that it is possible to solve it without disabling Auto Layout.Saffian
K
1

Try this code to auto set content size

first copy and paste your view controller in viewDidLoad Method

 [self MHAutoContentSizeForScrollViewWithPadding:10 scrl:YOUR_SCROLLVIEW];

then copy and paste in below viewDidLoad Method

-(void)MHAutoContentSizeForScrollViewWithPadding:(CGFloat)padding scrl:(UIScrollView*)view{
    if ([view isKindOfClass:[UIScrollView class]]) {
        CGRect rect = CGRectZero;
        for(UIView * view in YOUR_SCROLLVIEW.subviews){
            rect = CGRectUnion(rect, view.frame);
        }
        [YOUR_SCROLLVIEW setContentSize:CGSizeMake(rect.size.width, rect.size.height+padding)];
    } else {
        NSLog(@"You can only set the ContentSize for ScrollViews");
    }
}

connect YOUR_SCROLLVIEW delegate also and TextFeild Delegate also Happy Coding!!!

Kasi answered 22/1, 2014 at 4:20 Comment(0)
A
1

If you are using auto-layout than Put everything in the UIScrollView into another UIView, and put that UIView as the only child of the UIScrollView. Then you can use AutoLayout.

If things near the end is messed up (the end of whichever direction your UIScrollView scrolls), change the constraint at the end to have the lowest possible priority.

Aniakudo answered 22/1, 2014 at 4:41 Comment(0)
B
0

I had this issue and none of the answers in this thread worked.

I had set a top constraint of one of my subviews within the my UIScrollView equal to the UIViewController's view.topAnchor. My UIScrollView would therefore not scroll as it would break the constraint.

Once I amended the constraint and set it equal to my UIScrollView.topAnchor it worked as expected.

Bookbindery answered 25/6, 2020 at 21:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.