(Scale) Zoom into a UIView at a point

akaru picture akaru · Mar 27, 2011 · Viewed 26.8k times · Source

Something I don't understand about transformations. I want to zoom in to say the top right corner of a UIView (the main view). I use CGAffineTransformScale and have tried both setting the center/anchorPoint as well as CGAffineTransformMakeTranslation to no avail.

I can't figure out how to set the translation properly so that it will zoom in on this point.

CGAffineTransform tr = CGAffineTransformScale(self.view.transform, 2, 2);

[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
            self.view.transform = tr;
            self.view.center = CGPointMake(480,0);

} completion:^(BOOL finished) {}];

Answer

mvds picture mvds · Mar 27, 2011

You are setting the center of the view to the top right corner. That means you're zooming in on somewhere to the lower left of the center.

Try this

CGAffineTransform tr = CGAffineTransformScale(self.view.transform, 2, 2);
CGFloat h = self.view.frame.size.height;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(0,h);
} completion:^(BOOL finished) {}];

This will set the center of the blown-up view to the left bottom corner, effectively zooming in with the top right corner fixed.

This code doesn't have the height hardcoded, which is a little more portable (to an iPad of iPhone 5).

You need to first save h before setting the transform property, because after that you should not rely on the value of frame.

edit

To make it work for any scale s, use this:

CGFloat s = 3;
CGAffineTransform tr = CGAffineTransformScale(self.view.transform, s, s);
CGFloat h = self.view.frame.size.height;
CGFloat w = self.view.frame.size.width;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(w-w*s/2,h*s/2);
} completion:^(BOOL finished) {}];

To make it work for bottom left, use this:

CGFloat s = 3;
CGAffineTransform tr = CGAffineTransformScale(self.view.transform, s, s);
CGFloat h = self.view.frame.size.height;
CGFloat w = self.view.frame.size.width;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(w*s/2,h-h*s/2);
} completion:^(BOOL finished) {}];

To make it work for bottom right, use this:

CGFloat s = 3;
CGAffineTransform tr = CGAffineTransformScale(self.view.transform, s, s);
CGFloat h = self.view.frame.size.height;
CGFloat w = self.view.frame.size.width;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(w-w*s/2,h-h*s/2);
} completion:^(BOOL finished) {}];

See also: How to scale (zoom) a UIView to a given CGPoint