4
votes

I'm creating a UIView from a xib to eventually render into a UIImage.

The UIView itself has internal constraints which work fine given a large enough frame size in IB. However, I need to size the width to some particular content, and I can't figure out how to set the width of the UIView after loading it from a xib.

[[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil][0];

To render the view, I do this:

UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

No matter what I set the bounds to, however, the UIView is the same size as the initial size in IB. How can I set the size of the UIView such that it will cause internal constraints to resize and render correctly?

1
If you're using auto layout, you probably need to add a constraint to specify the new width (and remove the existing width constraint if there is one). Setting frames directly doesn't always work if you use layout constraints.Greg
I tried setting a width constraint programmatically and that also wasn't successful.Stefan Kendall
Could it be possible that UIView delays its internal update after the frame change to the next run loop? I've run into problems with this before, and wrapping subsequent rendering code in a dispatch_async on the main thread usually fixed it (but then again, setting width constraints programmatically also always worked for me, so you might have something else causing the problem).Greg

1 Answers

7
votes

Try setting the desired frame of the view and then calling layoutIfNeeded on it:

UIView *view = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil][0];
CGRect finalFrame = CGRectMake(0, 0, 90, 90);
view.frame = finalFrame;
[view layoutIfNeeded];

UIGraphicsBeginImageContextWithOptions(finalFrame.size, NO, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();