How to do this correctly.
UIViewController subclass should override the method
viewWillLayoutSubviews, see also here.
When this method is called, the viewController's
view has its correct size and you can make any necessary adjustments to subviews prior to the layout pass over the subviews.
When a view's bounds change, the view adjusts the position of its subviews. Your view controller can override this method to make changes before the view lays out its subviews. The default implementation of this method does nothing.
As you see from the emphasised part, this method is called every time the view controller's view changes size, as well as when the view first appears. This lets you respond correctly to rotation and other bounds change events
Some wrong ways to do this.
A couple of methods suggested by other answers here
do not work well are completely broken. You really shouldn't use these methods. Here they are, with why you should avoid them. Please.
viewWillAppear – during these calls
view does not yet have its final size. The size you get will only ever be correct by pure chance, so as to mislead you. Please, I beg you, don't use these methods.
viewDidAppear – this is too late. Your view is already on screen and visible to the user. Making changes here will cause visible changes / abrupt glitches and will look like terrible amateur hour rubbish. Once again, please – for your sake, for my sake, for everyone's sake: don't do it! You're better than that and so are your users.
Other than not providing correct information, these broken approaches will not help you with auto-rotation or other events that cause the view controller's view to change size such as multitasking gestures. This is something that you really want to handle smoothly.
So please: be a champ. Do it the right way. Use
viewWillLayoutSubviews. Your implementation will be called for every size change, and your users, future self, team members and I will celebrate you for it. Bravo!
viewWillLayoutSubviews is called, the only view in your hierarchy that will be resized to its final size is
viewController.view. The give away for this is in the name of the method. It's telling you
view… (your view controller's
…WillLayout… (really soon now, but it's not happened yet)
…Subviews (everything else in its hierarchy under the root view).
But it's not happened yet. So every single child under the root does not yet have a valid final size. Any size information you query from the child views will be at best completely wrong.
Rather more likely, and infinitely worse, it will be misleadingly correct!
It happens to be what you expect and need due to a default at this size and orientation, or due to your storyboard settings. But this is only by chance and isn't something you can rely on with different device sizes or orientations.
If you need to be told when a particular subview changes size, and know its exact final size, you should override the
layoutSubviews method of that particular