If your code relies on the coordinates of a view's frame, then your best bet is reading the frame in:
- (void)viewWillAppear:(BOOL)animated
You may be tempted to use - (void)viewDidLoad for the same purpose, which gets called earlier in the lifecycle, however at that time the frame may not have its value set accurately. I find this happening often especially for iPad. Most times I use the storyboard (and IB in the past) to implement my UIs. I usually lay it out in portrait mode only, and rely on the autoresizing mask, or layout constraints, to position everything properly. Because on iPad you can launch an app in landscape mode directly, the frame in viewDidLoad will appear as defined in the storyboard, with the size for portrait. If those values are relied upon later, that would result in problems.
This problem may also occur in obscure contexts, where one is not directly using the frame. For example in a previous post I was mentioning some weird behaviour when setting the value of a progress bar, like so:
[self.progressBar setProgress:0.5 animated:YES];
Apple took a look at it and informed me that "The view animates from an undefined state. Doing such things in the viewDidLoad can only lead to problems.".
Update:
While watching the slides from Stanford's iOS Programming course I discovered that in case that autolayout is used, instead of using viewWillAppear to get the view's geometry, one must use
- (void)viewDidLayoutSubviews
Apparently the latter is guaranteed to be called each time the bounds of the view change, and by the time that happens all the autolayout constrains would have been processed and the geometry would have been established.
No comments:
Post a Comment