ksn ksn - 18 days ago 6
iOS Question

UIViewController viewDidLoad incorrect width/height

Everybody knows that you can't trust the frame size on a UIViewController init/viewDidLoad method; this:

- (void)viewDidLoad: {
NSLog(@"%d", self.view.frame.size.width);

will print wrong sizes in many occasions (in particular it's pretty much broken in landscape mode)

This will actually return always corrected results so it's good to layout the subviews:

- (void)viewWillAppear: {
NSLog(@"%d", self.view.frame.size.width);

The problem is that viewWillAppears gets called every time the view appears, so it's not suitable to alloc or add subviews. So you end up declaring every single view in the interface and you end up with huge header files that I don't like at all since most of the items don't need any more manipulations after the initial setup.

So question one is: Is there a better way to handle subviews positioning?

Question two is very related, let's say I have a subclass of UIView including various others subviews. I declare it inside my interface, and i alloc/init it in my init/viewDidLoad method.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
menu = [[SNKSlidingMenu alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

As we already know we now need to reposition it in viewWillAppear to get a more accurate reading

- (void)viewWillAppear:(BOOL)animated{
menu.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

The problem is that of course all the subviews needs to be repositioned as well. This is done by the layoutSubviews function that get called automatically, but we got the same problem: All the subviews need to be declared inside the interface of the SNKSlidingMenu class.. Is there a way around this?


pgb pgb

If you are targetting iOS 5.0 or better you can use viewWillLayoutSubviews and viewDidLayoutSubviews to make changes.

As for your second question, if you need access to an instance variable in other method than init, you need to keep it around, I don't see a problem with it.

You can, however, try to use Auto Layouts and set up rules between the subviews so it's automatically laid out for you without the need to keep a reference.