UIScrollView setContentSize doesn't work

21,213

Solution 1

I had the same issue until I realized I hadn't set the UIScrollView delegate. Also, if you're using auto layout, you need to wait for the layout to be applied to the UIScrollView. This means you should set the Content Size in "viewDidLayoutSubviews".

Solution 2

In viewDidLoad method, frame may not be correct, move the code to this method:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    // Your code

}

Solution 3

Use this code. ScrollView setContentSize should be called async in main thread.

Swift:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    DispatchQueue.main.async {
        var contentRect = CGRect.zero

        for view in self.scrollView.subviews {
           contentRect = contentRect.union(view.frame)
        }

        self.scrollView.contentSize = contentRect.size
    }
}

Objective C:

 - (void)viewDidLayoutSubviews {
     [super viewDidLayoutSubviews];

     dispatch_async(dispatch_get_main_queue(), ^ {
                        CGRect contentRect = CGRectZero;

                        for(UIView *view in scrollView.subviews)
                           contentRect = CGRectUnion(contentRect,view.frame);

                           scrollView.contentSize = contentRect.size;
                       });
}

Solution 4

Okay, there is absolutely nothing wrong with your code. So some suggestions:

  1. Make sure you added to your .h file like so:

    @interface yourViewController : UIViewController <UIScrollViewDelegate> {
    
     }
    
  2. Try moving this snippet of code to the "viewWillLoad" method:

    - (void)viewWillAppear:(BOOL)animated {
         self.scrollView.delegate = self;
         [self.scrollView setScrollEnabled:YES];
    
         [self.scrollView setContentSize:CGSizeMake(self.view.frame.size.width, 20000)];
    }
    
Share:
21,213
anthoprotic
Author by

anthoprotic

Updated on June 06, 2020

Comments

  • anthoprotic
    anthoprotic almost 4 years

    I have a really big problem with UIScrollView. To make sure it wasn't my actual project, I created a NEW project, iPhone only, for iOS 6 and 7. I disabled autolayout.

    1. I created a Tab Bar project
    2. I created a view controller, embedded it in a navigation controller and connected it as Tab bar item #0
    3. I put a UIScrollView in my view.
    4. I connected the scrollview in the custom UIViewController created for this view.
    5. I synthesized my IBOutlet and set the delegate to self. I also implemented delegate in .h

    Here is my code (ViewDidLoad):

        self.scrollView.delegate = self;
        [self.scrollView setScrollEnabled:YES];
    
        [self.scrollView setContentSize:CGSizeMake(self.view.frame.size.width, 20000)];
    
    
        NSLog(@"contentSize width %f", self.scrollView.contentSize.width);
        NSLog(@"contentSize height %f", self.scrollView.contentSize.height);
    
        NSLog(@"%@", NSStringFromCGAffineTransform(self.scrollView.transform));
    

    It returns me "contentSize width 20000.000000", "contentSize height 0.000000 " and "[1, 0, 0, 1, 0, 0]". It scrolls left-right where it should scroll up-down

    Please help!

  • anthoprotic
    anthoprotic over 10 years
    Doesn't change a thing, unfortunately.
  • quaertym
    quaertym over 10 years
    Also check for orientation
  • anthoprotic
    anthoprotic over 10 years
    What do you mean? My scrollview takes all the space on my ViewController
  • quaertym
    quaertym over 10 years
    Are you sure that self.view is not nil and self.view.frame is correct?
  • anthoprotic
    anthoprotic over 10 years
    Yes, I NSLogged it and self.view isn't nil. And I tried [self.scrollView setContentSize:CGSizeMake(1500, 20000)]; doesn't change a thing.
  • anthoprotic
    anthoprotic over 10 years
    I know right! That's what really frustrating. I tried your way, but viewWillLoad doesn't get called. Never.
  • anthoprotic
    anthoprotic over 10 years
    I created a completely NEW project only to test my UIScrollView code (like above). Nothing can be corrupted. Can it be a setting in my .plist that still thinks autolayout it activated? I'm using Xcode 5.0.2
  • quaertym
    quaertym over 10 years
    Did you disable autolayout for all of your view controllers in the storyboard?
  • JustAnotherCoder
    JustAnotherCoder over 10 years
    Sorry I didn't mean viewWillLoad, try viewWillAppear
  • hatfinch
    hatfinch over 10 years
    NB there is no "-viewWillAppear" method, only "-viewWillAppear:(BOOL)animated".
  • anthoprotic
    anthoprotic over 10 years
    I disabled autolayout in the view inspector, which disables autolayout all over the app I think. I tried putting the code inside - (void) viewDidAppear:(BOOL)animated, didn't work too.
  • anthoprotic
    anthoprotic over 10 years
    Sorry, I meant - (void) viewWillAppear:(BOOL)animated
  • anthoprotic
    anthoprotic over 10 years
    I'm now starting to get desperate about this. Could someone create a new project with only 1 view controller and a UIScrollView that scroll up and down with autolayout disabled? If I can't get your project to work on my computer, I'll know what's up.
  • Code Hunter
    Code Hunter over 10 years
  • Eloy
    Eloy almost 10 years
    Thanks! I didn't get my scrollview to work either, until I read your answer, and set the content size in viewDidLayoutSubviews.
  • Alyoshak
    Alyoshak almost 10 years
    Setting the contentSize property in viewDidLayoutSubviews worked for me. Had nothing to do with auto layout.
  • fischgeek
    fischgeek almost 9 years
    Oh my gosh. After days of endless searching and messing with all kinds of solutions to no avail, this post was the answer. Thank you so much.