Iulian Onofrei
Iulian Onofrei

Reputation: 9720

Translate and scale UIView in Objective-C

I want to animate a view by centering one of it's points to the center of the screen and then scale it up.

So, if I have this screen (S) with a view (V) in it, and a certain point (x):

+-------------+
|S-----------+|
||V          ||
||           ||
||           ||
||           ||
||           ||
||  x        ||
||           ||
|+-----------+|
+-------------+

I want it to animate to this position:

   +-----------+
+---V---------+|
|S |          ||
|  |          ||
|  |          ||
|  |          ||
|  |   x      ||
|  |          ||
|  +----------|+
|             |
|             |
+-------------+

where the point is centered in the screen, and then scale it like this:

+-------------------+
|V                  |
|                   |
|                   |
|                   |
|+-------------+    |
||S            |    |
||             |    |
||             |    |
||             |    |
||      x      |    |
||             |    |
||             |    |
||             |    |
||             |    |
|+-------------+    |
+-------------------+

however, I can't accomplish this, even using CGAffineTransformConcat, which I though is it designed exactly for cases like this.

I have tried this:

CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(deltaPoint.x, deltaPoint.y);
CGAffineTransform scaleTransform = CGEqualAffineTransformMakeScale(40);

self.screenView.transform = CGAffineTransformConcat(translateTransform, scaleTransform);

where deltaPoint is a CGPoint having it's x and y equal to the distance between the point's absolute coordinates (relative to the screen) and the coordinates of the center of the screen, but it animates the point slightly to the right.

I also tried calculating the deltaPoint after scaling to no avail:

self.screenView.transform = CGEqualAffineTransformMakeScale(40);

// calculate deltaPoint

self.screenView.transform = CGAffineTransformTranslate(self.screenView.transform, deltaPoint.x, deltaPoint.y);

In both cases, if I comment out the scaling transform, the translation works, it moved it perfectly center, so the problem isn't in the deltaPoint calculation.

Upvotes: 1

Views: 2819

Answers (3)

sahara108
sahara108

Reputation: 2859

You want to scale your view with scale factor (Sx, Sy) and move the point (x0, y0) to (x1, y1). And you calculated dx,dy. So let do some calculation:

Sx.x0 + a = x0 + dx => a = dx - (Sx-1).x0
Sy.y0 + b = y0 + dy => b = dy - (Sy-1).y0

With Sx = Sy = 40 so we have a = dx - 39.x0 and b = dx - 39.y0. So we have transform vector like that

CGAffineTransform scaleTransform = CGAffineTransformMake(40, 0, 0, 40, a, b);
self.screenView.transform = CGAffineTransformConcat(translateTransform, scaleTransform);

x0, y0 is your original point x in view v, before any transformation. You can call it pointX.x, pointX.y. You are using scale factor is 40 in your example so I re-use it. So that Sx-1 and Sy - 1 will return the same value, 39.

Upvotes: 2

Y.Bonafons
Y.Bonafons

Reputation: 2349

I suppose screenView is your view (V)

so you can try something like this:

[UIView animateWithDuration:2 // put translation duration here
                 animations:^{
                     self.screenView.center = CGPointMake(self.screenView.center.x + deltaPoint.x, self.screenView.center.y + deltaPoint.y);
                 }
                 completion:^(BOOL finished) {
                     [UIView animateWithDuration:2 // put scale duration here
                                      animations:^{
                                          self.screenView.transform = CGAffineTransformMakeScale(1.1, 1.1); // here the final size will be 110%
                                      }
                                      completion:nil];
                 }
 ];

If you want to do this at the same time so simply put the scale in the same block:

[UIView animateWithDuration:2 // put translation duration here
                 animations:^{
                     self.screenView.center = CGPointMake(self.screenView.center.x + deltaPoint.x, self.screenView.center.y + deltaPoint.y);
                     self.screenView.transform = CGAffineTransformMakeScale(1.1, 1.1); // here the final size will be 110%
                 }
                 completion:nil
 ];

Upvotes: 0

Mousam
Mousam

Reputation: 63

What I understood is after the view v and point x translates to its required position, you wanted view to be scaled up from the point x, so even after scaling point x remains in the centre of the screen, If it is TRUE then after translation, you need to adjust the anchor point of view such that anchor point of view is equal to x.

Upvotes: 0

Related Questions