9

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
  • 827
  • 2
  • 13
  • 24
  • 1
    are you using autolayout? – Jumhyn Dec 11 '13 at 21:39
  • As stated at the beginning, I disabled it. Screws up too many things in the app – anthoprotic Dec 11 '13 at 21:42
  • Don't you mean the log reads 20000 for the height and 0 for the width? – bilobatum Dec 12 '13 at 00:12
  • No, and that's the problem! It only scrolls in the left-right axis, where I want it to scroll in the up-down axis only – anthoprotic Dec 12 '13 at 00:15
  • are you developing on xcode 5 ??? there's an option in the attribute inspector, ( Autoresize Subview ), make sure it is not checked, this is only in the new Xcode, i'm not sure if it will solve your problem, but it might :) – Nour Helmi Dec 12 '13 at 02:10
  • Try to give the frame of the Scroll view in the code..just to be sure – Ishank Dec 12 '13 at 04:47
  • @Nour1991 Yes I'm on Xcode 5.0.2, I tried disabling Autoresize Subview on my scrollview and on my view inside my view controller, but the NSLog is still 20000 for width and 0 for height. – anthoprotic Dec 12 '13 at 12:37
  • mmmmm i don't know buddy what's going on, this is so weird :\ 2 more things to try: **A.** try to delete the app from the simulator, clean your project, and then reinstall, and see if anything will change. **B.** try to create a new project that has only the code in your question, and see if anything changes. P.S: are you using external libraries ?? like stuff in cocoapods or anything ?!? (( one of them might be causing this weir behaviour, although highly unlikely )) – Nour Helmi Dec 13 '13 at 00:14
  • No, nothing not standard, and I really tried all this :\ – anthoprotic Dec 13 '13 at 15:35

5 Answers5

41

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".

mr.sosa
  • 691
  • 7
  • 13
  • Thanks! I didn't get my scrollview to work either, until I read your answer, and set the content size in viewDidLayoutSubviews. – Eloy May 28 '14 at 18:08
  • Setting the contentSize property in viewDidLayoutSubviews worked for me. Had nothing to do with auto layout. – Alyoshak Jun 12 '14 at 14:42
  • 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. – fischgeek Jun 09 '15 at 16:34
8

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

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    // Your code

}
quaertym
  • 3,917
  • 2
  • 29
  • 41
6

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;
                       });
}
Karen Hovhannisyan
  • 1,140
  • 2
  • 21
  • 31
3

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)];
    }
    
JustAnotherCoder
  • 2,565
  • 17
  • 38
  • I know right! That's what really frustrating. I tried your way, but viewWillLoad doesn't get called. Never. – anthoprotic Dec 12 '13 at 00:38
  • 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 – anthoprotic Dec 12 '13 at 00:39
  • Did you disable autolayout for all of your view controllers in the storyboard? – quaertym Dec 12 '13 at 00:48
  • Sorry I didn't mean viewWillLoad, try viewWillAppear – JustAnotherCoder Dec 12 '13 at 04:26
  • NB there is no "-viewWillAppear" method, only "-viewWillAppear:(BOOL)animated". – hatfinch Dec 12 '13 at 11:52
  • 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 Dec 12 '13 at 12:41
  • Sorry, I meant - (void) viewWillAppear:(BOOL)animated – anthoprotic Dec 12 '13 at 12:41
  • 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. – anthoprotic Dec 12 '13 at 12:44
  • Please try this link http://stackoverflow.com/questions/12846351/uiscrollview-contentsize-not-working – Code Hunter Dec 12 '13 at 17:13
0
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    var contentRect = CGRect.zero
    for view: UIView in scrollView.subviews {
        if !view.isHidden {
            contentRect = contentRect.union(view.frame)
        }
    }

    scrollView.contentSize = contentRect.size
    scrollView.contentSize.width = self.view.frame.width
}

Working Swift 3.X code. Converted @Karen Hovhannisyan's answer.

Karen Hovhannisyan
  • 1,140
  • 2
  • 21
  • 31
anuraagdjain
  • 86
  • 2
  • 7