Bounds and Frame size in viewDidLoad

主宰稳场 提交于 2020-01-04 06:03:30

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/12680377/bounds-and-frame-size-in-viewdidload

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!