2

I push a view controller (mainVC) and add some subviews to it. Most of these views are built on-demand, as the user takes some action.

When I build each view, I refer to mainVC.view.bounds to size the view. The ones that are built on demand size just fine, but the first one (which I add in viewDidLoad) does not seem to account for either the hidden navigation bar or the unhidden toolbar - I'm not sure which.

Other questions seem to assure me that viewDidLoad is the correct place to refer to the bounds and to add these subviews. Am I misinformed? Logging yields the following:

In viewDidLoad the bounds height is 548.

In viewWillAppear the bounds height is 460 (-44 x 2). In viewWillAppear I hide the navigation bar, but the height is the same before and after.

At all later times, the bounds height is 504 (-44 x 1).

Why is the bounds height not updated by the time I attempt to read it in viewDidLoad?

Ben Packard
  • 26,102
  • 25
  • 102
  • 183
  • I assume that when the nib is first loaded, the view is whatever size you set it. When its ends up as a subview in the window, the system sizes it appropriate for where its located (I assume). Note there is no "hard" size - I have tethering enabled so the view is 20 pixels shorter than normal. – David H Oct 01 '12 at 21:35

1 Answers1

5

The view controller lifecycle is described in View Controller Programming Guide for iOS.

In short, when -view is called the first time, -viewDidLoad is called. Even if the very first thing a view controller does to a view is set the frame, it still needs to access the view.

UIViewController *controller = [MyViewController myViewController];

// -viewDidLoad has not been called (if +myViewController doesn't call -view.)

UIView *view = [controller view];

// -viewDidLoad has been called.

view.frame = [UIApplication sharedApplication].delegate.window.bounds;

Even if you use controller.view.frame the same logical sequence happens. -viewDidLoad will always be a called with a freshly deserialized view that has not been embedded into the view hierarchy.


Update

It case it wasn't clear earlier, I was pointing out why the bounds of view are not set correctly in -viewDidLoad. It is only after -viewDidLoad does the view controller's view get added to the view hierarchy. This is when the final frame of the view is set.

If you must have the frame be the right dimensions, you can use IB to set the dimensions that you know you'll need or (if you don't use IB) set the frame in -loadView. This approach is flawed because it statically sets the size of the frame to a value that may be changed after -viewDidLoad is called (things like the in-call status bar).


Update 2

You need to split the adding subviews from positioning and sizing subviews.

If you are loading from a Storyboard or a Nib, then you are correct, additional views needed should be added in -viewDidLoad. If you're loading programmatically, then all subviews are added in -loadView.

The second task is positioning and sizing subviews. The preferred method is to use UIView.autoresizingMask, but for more precise layout, KVO view.bounds and adjust your custom subviews when view controller's view changes its size.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • Even if I request [controller view] immediately after creating the controller, it makes no difference. First I create the controller. Second, I (for now) just assign the controller's view to a variable - just to reference it. Then I change the frame. For any demand-loaded cycles this works - for any triggered in the view didLoad of the mainVC, it does not. If I have misunderstood, and you are referring to my mainVC in your example, then how am I meant to load some other view controllers at launch, and add their views? – Ben Packard Oct 02 '12 at 15:51
  • Sorry, maybe I wasn't clear`-viewDidLoad` will always be called before the final bounds or frame is set. Always. There is nothing you can do about it. – Jeffery Thomas Oct 02 '12 at 15:58
  • Where should I add subviews? In viewWillAppear? Seems like I would be doing a lot of unnecessary reprocessing. – Ben Packard Oct 02 '12 at 16:19
  • The short answer is split add subviews from positioning and sizing subviews. – Jeffery Thomas Oct 02 '12 at 16:55
  • @Jeffery Thomas: I have a similar question here, I think your feedback would be useful: http://stackoverflow.com/questions/17882199/view-height-problems-continued – user2054339 Jul 26 '13 at 14:51