Ios – Custom UI View Change frame size

iosipadiphoneobjective c

I have a custom UIView that draws an image in the draw rect method. My problem is UIView wants me to initWithFrame when I allocate the object. The frame of the view needs to be the same as the image size and width. The problem is that I don't get that image size and width until the drawRect method of the view I am creating. Inside the drawRect view changing the UIView's frame to the image dimensions seems to have no effect. So what I want to do is something like this:

MyCustomView *myCustomView = [[MyCustomView alloc] initWithFrame: CGrectMake(0,0,0,0)];

Then inside MyCustomView's drawRect method I want to somehow change the frame of the view to be the frame size of the image I am creating.

How do I get my desired outcome? An no, creating the image before I init my custom view and putting the size dimensions into the initWithFrame is not an option.

This is my current code in the view's drawRect method

UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",self.imgName]];
CGSize imgSize = [image size];
CGRect newrect = CGRectMake(self.frame.origin.x, self.frame.origin.y, imgSize.width, imgSize.height);
self.frame = newrect; //This does nothing!!
CGRect imgRect = CGRectMake(0, 0, imgSize.width, imgSize.height);
[image drawInRect:imgRect];

Best Answer

If you look at the docs for setFrame it says:

This method, in setting the frame rectangle, repositions and resizes the receiver within the coordinate system of its superview. It neither redisplays the receiver nor marks it as needing display. You must do this yourself with display or setNeedsDisplay:.

It will not redisplay - typically after setting the frame you call setNeedsDisplay. but, this highlights your chicken and egg problem. setNeedsDisplay causes drawrect to fire.

Also, as Sulthan pointed out, doing something heavy like loading images in drawRect is not a good idea. It's heavy weight and things like drawRect get called repeatedly on resize etc...

I would either create an init pattern (even though you said not an option), or create a property to set the image and have the image load at that time.

Related Topic