akaru akaru - 1 month ago 17
iOS Question

(Scale) Zoom into a UIView at a point

I've been stuck on this for days. 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

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: Scale (Zoom) UIView to given CGPoint