在 Objective-C 中转换和缩放 UIView

Translate and scale UIView in Objective-C

我想通过将其中一个点置于屏幕中心然后将其放大来为视图设置动画。

所以,如果我有这个屏幕 (S),其中有一个视图 (V),以及某个点 (x):

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

我想让它动画到这个位置:

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

点在屏幕中心的位置,然后像这样缩放:

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

然而,即使使用 CGAffineTransformConcat,我也无法做到这一点,但我认为它正是为这种情况而设计的。

我试过这个:

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

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

其中 deltaPoint 是一个 CGPoint,它的 xy 等于点的绝对坐标(相对于屏幕)与点的坐标之间的距离屏幕的中心,但它使该点稍微向右移动。

我也试过在缩放后计算 deltaPoint 无济于事:

self.screenView.transform = CGEqualAffineTransformMakeScale(40);

// calculate deltaPoint

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

在这两种情况下,如果我注释掉缩放变换,翻译有效,它完美地将它移动到中心,所以问题不在 deltaPoint 计算中。

我的理解是视图v和点x平移到它需要的位置后,你希望视图从点x放大,所以即使缩放后点x仍然在屏幕的中心,如果它为TRUE则翻译后需要调整锚点视角使锚点视角等于x。

我想 screenView 就是你的视图 (V)

所以你可以尝试这样的事情:

[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];
                 }
 ];

如果您想同时执行此操作,只需将秤放在同一块中即可:

[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
 ];

您想使用比例因子 (Sx, Sy) 缩放视图并将点 (x0, y0) 移动到 (x1, y1)。你计算了dx,dy。所以让我们做一些计算:

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

有了 Sx = Sy = 40 所以我们有 a = dx - 39.x0b = dx - 39.y0。所以我们有这样的变换向量

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

x0, y0 是您在视图 v 中的原始点 x,在任何转换之前。你可以称它为pointX.x, pointX.y。 你在你的例子中使用的比例因子是 40 所以我重新使用它。这样 Sx-1Sy - 1 将 return 相同的值, 39.