9
votes

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!

5
are you using autolayout?Jumhyn
As stated at the beginning, I disabled it. Screws up too many things in the appanthoprotic
Don't you mean the log reads 20000 for the height and 0 for the width?bilobatum
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 onlyanthoprotic
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 :)Nour1991

5 Answers

40
votes

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

8
votes

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

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    // Your code

}
6
votes

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;
                       });
}
3
votes

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)];
    }
    
0
votes
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.