stackQA
stackQA

Reputation: 336

UIViewController Methods viewDidLoad/viewWillHappen - view frame size detection

I have written some code which applies and image to a view for a UIViewController. The code is supposed to be iPhone screensize independent in as far as the difference in height between the iPhone 4 and 5.

      self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
      self.view.clipsToBounds = YES;
      UIGraphicsBeginImageContext(self.view.frame.size);
      [[UIImage imageNamed:@"myimage.png"] drawInRect:self.view.bounds];


      UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      UIView *imageView = [[UIView alloc] initWithFrame:CGRectMake(0,0,      self.view.frame.size.width, self.view.frame.size.height)];
      imageView.backgroundColor = [UIColor colorWithPatternImage:image];
      [self.view addSubview: imageView];

      image =  nil;
      imageView = nil;

I found that when I add this code to the viewDidLoad method, the code failed to detect the different window size. However when I place it in viewWillAppear, the code does correct work with both screen sizes. I don't understand why.

Does any one know why this would happen ? I would like to understand it.

thanks

Upvotes: 0

Views: 337

Answers (3)

rmaddy
rmaddy

Reputation: 318814

What you are doing is almost correct. As others have stated, in viewDidLoad the final size of the view controller's view is not set yet. The proper solution is to set the subview's autoresizingMask properly.

UIView *imageView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height)];
imageView.backgroundColor = [UIColor colorWithPatternImage:image];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.view addSubview: imageView];

This assumes you want the image view to fill the view controller's view.

Another solution is to update the frames of the subviews in the viewWillLayoutSubviews method.

Upvotes: 0

Travis
Travis

Reputation: 3369

This happens because at the time the view is loaded, its' content hasn't necessarily been laid out and the size isn't known. This is especially true when using the autolayout system. The basic steps are,

  1. The view is loaded
  2. The view is laid out by the system using the constraints you give in the storyboard or code
  3. The view appears

So the most appropriate place to put this appears to be viewDidLayoutSubviews. At that point the view and its subviews have been laid out, and the sizes are there. But putting it in viewWillAppear (or viewDidAppear, for that matter) will work, albeit will be less correct.

Upvotes: 1

yurish
yurish

Reputation: 1535

viewDidLoad method is called when the view controller's root view just has been created. At this point it is not added to the window hierarchy and auto layout has not been done. That is why you see this behavior.

This being said why draw the image in the graphic context? Just use UIImageView to display the image.

Upvotes: 0

Related Questions