Proper transform for scaling a UIView from a rect?

akaru picture akaru · Jan 30, 2013 · Viewed 7.8k times · Source

I want to mimic "zooming in" on a view. The larger view will be added as a subview to the smaller view's superview, and the larger view should look as if it is zooming in from the smaller view. Given the rect of the smaller view fromRect and the final frame of the zoomed in larger view finalRect, what would be the proper transform?

enter image description here

I imagine the method signature would be like the following, with view being the superview. I wrote this up to help myself, but cannot figure it out yet.

-(CGAffineTransform) translatedAndScaledTransformUsingViewRect:(CGRect)viewRect fromRect:(CGRect)fromRect inView:(UIView*) view
{
//calculate the scaling based on the final frame of viewToBeStretched (viewRect) vs the "fromRect"
CGFloat scaleX = ?, scaleY = ?;
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(scaleX, scaleY);

//use translation instead of modifying the view's center, since frame changes with transforms are no good
CGFloat translationX = ?, translationY =?;
CGAffineTransform translationTransform = CGAffineTransformMakeTranslation(translationX, translationY);

CGAffineTransform final = CGAffineTransformConcat(scaleTransform, translationTransform);

return final;
}

Answer

Skie picture Skie · Feb 8, 2013

So actual implementation is very simple:

- (CGAffineTransform)translatedAndScaledTransformUsingViewRect:(CGRect)viewRect fromRect:(CGRect)fromRect {

    CGSize scales = CGSizeMake(viewRect.size.width/fromRect.size.width, viewRect.size.height/fromRect.size.height);
    CGPoint offset = CGPointMake(CGRectGetMidX(viewRect) - CGRectGetMidX(fromRect), CGRectGetMidY(viewRect) - CGRectGetMidY(fromRect));
    return CGAffineTransformMake(scales.width, 0, 0, scales.height, offset.x, offset.y);

}

You can see full example here: https://github.com/vGubriienko/TransformTest

(I still need update it to use identity as full image)