wrong frame size in viewDidLoad

33,156

Solution 1

It's a very similar question to ios setContentOffset not working on iPad ... And my answer is the same as there:

"You should not initialise UI geometry-related things in viewDidLoad, because the geometry of your view is not set at this point and the results will be unpredictable.

... viewWillAppear: is the correct place to do these things, at this point the geometry is set so getting and setting geometry-related properties makes sense."

This also applies to getting geometry-related properties. Don't get distracted by it's behaving correctly in one circumstance and not in another... The main point is that setting/getting geometry properties too early will yield unpredictable results.

Your screen looks correct because you are seeing the results after viewWillAppear: / viewDidAppear:.

update (ios6)

When using autolayout in ios6, frames are not set until subviews have been laid out. The right place to get frame data under these conditions is in the viewController method viewDidLayoutSubviews.

This is called after viewWillAppear:. But take care - they are not always called together. For example, viewDidLayoutSubviews is called after a rotation, viewWillAppear: is not. viewWillAppear: is called every time a view becomes the visible view*, viewDidLayoutSubviews not necessarily (only if the views needed relaying out).

(* unless the app was backgrounded and is becoming the foreground app, then viewWillAppear: is not called)

Solution 2

I figured it out why it happened. I was using AutoLayout. When I uncheck it in the storyboard then the frames are correct.

Share:
33,156
Oleg
Author by

Oleg

Updated on July 09, 2022

Comments

  • Oleg
    Oleg almost 2 years

    Possible Duplicate:
    Why am I having to manually set my view’s frame in viewDidLoad?

    I have universal app for iphone and ipad, two storyboards, if I run my app on the iphone simulator in viewDidLoad every frame of each element in nib is correct. But if I do it for ipad (simulator) in frame is nil, but the screen looks correct. Could you please advise me smth? Thanks.

  • Oleg
    Oleg over 11 years
    I checked and in viewWillAppear it is the same. All frames are nil. I don't know how to explain it for now.
  • foundry
    foundry over 11 years
    New in ios6 ... If you are using autolayout, the frames are not set until us views are laid out ... So if you need to check/ get frames do it in -viewDidLayoutSubviews.
  • Adam
    Adam about 11 years
    warning: "viewDidLayoutSubviews" is NOT called on auto-rotate if autolayout is not enabled. The whole of auto-layout is massively INcompatible with non-auto-layout (you actually have to change your source code. Ugh)
  • foundry
    foundry almost 11 years
    @Adam, I agree - autolayout is mostly not useful and horrendously incompatible with non-autolayouted ways of working. The worst thing is that it defaults to ON in Interface Builder, leading to a ton of needless questions and answers on SO. Note that this part of my answer was directed to those with the checkbox ON...
  • Kedar Paranjape
    Kedar Paranjape almost 9 years
    Also, as the docs state, this method being called does not indicate that the individual layouts of the view's subviews have been adjusted. Thus, you may have to call setNeedsLayout and layoutIfNeeded if you're relying on a particular subview's size set via AutoLayout