I've spent a lot of time trying to find a way to use CGAffineScale to transform a view to a given point, including messing around with anchor points, moving the centre of a view before and after transforming and comprehensive Googling. I am aware this would be a lot simpler with a UIScrollview; but I know it's technically possible to do without one, and it's become a splinter in my mind.
This answer gets remarkably close to what I want to achieve, but the answer only gives details on how to zoom to a given corner (instead of a given point) by cleverly moving the centre to the corner opposite the one you want to zoom in to.
How can I modify mvds' code to scale a UIView to any given point in a UIView?
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) {}];
I actually ran into this very same problem myself. To fix it, all I did was change the anchor point of the view I was scaling because CGAffineTransforms are performed on the view in relation to its anchor point, so depending on where the anchor point is, the transform will scale, translate, or rotate the view differently. Here's the basic idea:
CGPoint pointToScaleTo = CGPointMake(x, y); //Just enter the coordinates you
//want to scale your view towards
CGFloat viewWidth = self.view.bounds.size.width;
CGFloat viewHeight = self.view.bounds.size.height;
CGFloat scaleFactorX = ...;
CGFloat scaleFactorY = ...;
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(scaleFactorX, scaleFactorY);
[UIView animateWithDuration:2.5f delay:0.0f options:0 animations:^{
//I divide the x and y coordinates by the view width and height
//because the anchor point coordinates are normalized to the range
//0.0-1.0.
self.view.layer.anchorPoint = CGPointMake(pointToScaleTo.x/viewWidth, pointToScaleTo.y/viewHeight);
//Now that the anchor point has been changed, apply the scale transform
self.view.layer.transform = scaleTransform;
} completion:^(BOOL finished) {}];
There are 2 steps involved: First you scale up the view you want to zoom in to. Then you set the center of this blown up view such that the part you want to see ends up in the middle of the view.
You should draw this out on paper and the formulas will follow: (untested)
CGFloat s = 3;
CGPoint p = CGPointMake(100, 200);
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;
CGFloat cx = w/2-s*(p.x-w/2);
CGFloat cy = h/2-s*(p.y-h/2);
self.view.center = CGPointMake(cx, cy); //was: (w*s/2,h-h*s/2);
} completion:^(BOOL finished) {}];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With