2

I created a view controller with a navigation bar on top, a tab bar at the bottom, and nothing but a UIScrollView that occupies all the remaining space in the middle. I've already created a weak, nonatomic IBOutlet for the scroll view on my view controller's header file. What I don't understand is how, when I print out its frame values from the owner view controller, the width and height values are zero.

This is the view controller's header file:

#import <UIKit/UIKit.h>

@interface AdGalleryViewController : UIViewController<UIScrollViewDelegate>
@property (nonatomic, weak) IBOutlet UIScrollView *scrollView;
@property (nonatomic, strong) NSArray *imageURLs;
@end

The implementation file:

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGRect svFrame = self.scrollView.frame;
    NSLog(@"scroll view frame: %@", NSStringFromCGRect(svFrame));
}

Output:

2013-07-05 15:36:21.447 Sulit[2733:907] scroll view frame: {{0, 0}, {0, 0}}

What is going on?

Matthew Quiros
  • 13,385
  • 12
  • 87
  • 132
  • 2
    Plz check youe scrollview connected with it's delegate and IBOutlet – chandan Jul 05 '13 at 07:47
  • Are you using autolayout ? – danypata Jul 05 '13 at 07:51
  • I am. I've also just connected the scroll view to the file owner as its delegate (just found out after the above comment that I hadn't done that), but still getting zeroes. – Matthew Quiros Jul 05 '13 at 07:53
  • The delegate doesn't have anything to do with the frame of the scroll view, please check your constraints seted for your scroll view and check the frame value in `viewWillAppear` or `viewDidAppear` – danypata Jul 05 '13 at 07:54
  • It's still zero when I remove Auto Layout. :( – Matthew Quiros Jul 05 '13 at 08:00
  • Delete your scroll view, add it again, and make sure you are linking it properly with the outlet. – danypata Jul 05 '13 at 08:12
  • When I remove Auto Layout from the storyboard it becomes effective for all the view controllers in it, and I'm afraid I don't I want that. Also this is beginning to feel like the problem is coming from somewhere else. I feel that the answers below should somehow suffice already. – Matthew Quiros Jul 05 '13 at 08:21

3 Answers3

3

In viewDidLoad: the views are loaded from the storyboard, but do not have the "correct" dimensions yet. To set/change dimensions use viewWillAppear: instead.

Martin Mandl
  • 721
  • 3
  • 11
  • If you don't use autolayout the size in `viewDidLoad` will be the exact size seted in sotryboard/xib files. – danypata Jul 05 '13 at 07:50
  • If I should do it in `viewWillAppear` how come this tutorial works though? (just look at where he's writing the code, no need to watch the whole thing) http://www.youtube.com/watch?feature=player_detailpage&v=vLUQz7TeE7w#t=484s – Matthew Quiros Jul 05 '13 at 08:05
  • try to use different orientations (landscape vs portrait), and you will see ;) – Martin Mandl Jul 05 '13 at 08:07
3

Accessing the frame property in viewDidLoad is not recommended since the view's position and dimensions are not fixed yet. You should do it in viewWillAppear:and you'll get non-zero values.

Barnabé Monnot
  • 1,163
  • 1
  • 9
  • 19
2

If you are using auto layout in a storyboard, a good place to check the frame of your UIScrollView is in viewDidLayoutSubviews. It is called after the storyboard has laid out the views, but before viewDidAppear:. I find it more reliable than viewWillAppear: when checking the frame of a view in a storyboard.

The methods are called in this order:

  1. viewDidLoad
  2. viewWillAppear:
  3. viewWillLayoutSubviews
  4. viewDidLayoutSubviews
  5. viewDidAppear:
Steph Sharp
  • 11,462
  • 5
  • 44
  • 81
  • Someone posted an answer that got downvoted and is now deleted, but it worked for me--setting the frame of the `UIScrollView` in `viewDidLoad`. Would you consider that a bad idea and why? – Matthew Quiros Jul 08 '13 at 09:54
  • Setting the frame of the `UIScrollView` in `viewDidLoad` may sometimes work, but it causes unpredictable results and should be avoided. Here are two SO answers that have good explanations of why `viewDidLoad` should not be used: [here](http://stackoverflow.com/a/6758424/1367622) and [here](http://stackoverflow.com/a/14064672/1367622). – Steph Sharp Jul 08 '13 at 14:57