iOS: setFrame no longer working from viewDidLoad or viewWillAppear

ios, ios6

Solution

I guess you want to layout your views from UIViewController. Have you tried performing your layout tasks in viewDidLayoutSubviews:

- (void)viewDidLayoutSubviews

According to Apple's documentation:

Your view controller can override this method to make changes after the view lays out its subviews.

Since your view itself does not do layout its subviews (you do not use autosize, autolayout or layoutSubViews:) you can do the layout tasks in this method.

Nevertheless, the elegant way would be to use a custom parent UIView and perform all the layout there, overriding UIView's `layoutSubViews:` (unless you add/removes views dinamically). Quote from Apple's documentation on "How View Controllers Participate in the View Layout Process":

Ideally, the views themselves perform all of the necessary work to reposition themselves, without requiring the view controller to participate in the process at all. However, if the view controller adds and removes views dynamically, a static layout in Interface Builder may not be possible. In this case, the view controller is a good place to control the process, because often the views themselves only have a limited picture of the other views in the scene.

Problem

I prefer to disable `autoresizesSubviews` and to use `setFrame` to place all of my subviews. As of iOS 6, things seem to have changed a lot. When I call setFrame on a view in `viewDidLoad`, there is no effect. I tried it from `viewWillAppear`; same thing. A setFrame call will work in `willAnimateRotationToInterfaceOrientation`, but that is not called initially like it was in iOS 5. Can someone clarify please where I am expected to layout my views from?

Original source