【问题标题】:Translate and scale UIView in Objective-C在 Objective-C 中翻译和缩放 UIView
【发布时间】:2015-07-17 07:13:57
【问题描述】:

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

所以,如果我有这个屏幕 (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 计算。

【问题讨论】:

  • @Eiko,我已经更新了问题。
  • 你有没有尝试过顺序颠倒的concat?
  • @Eiko,是的,但它仍然不起作用。

标签: objective-c frame cgaffinetransform


【解决方案1】:

您想使用比例因子 (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 将返回相同的值39

【讨论】:

  • 问题是设置anchorPoint后,我的view移动到了错误的位置,所以x的点已经不在中心了。
  • 我认为这是一个错误:CGAffineTransform t = CGAffineTransform scaleTransform = CGAffineTransformMake(40, 0, 0, 40, a, b);。还有,ab是什么?
  • 这是我复制粘贴时的错误。我已经给出了ab 的计算方法
  • x0y0 是转换前v 中的位置。
  • 39.x0 是什么意思?
【解决方案2】:

我的理解是在视图 v 和点 x 转换到其所需位置之后,您希望视图从点 x 放大,所以即使在缩放点 x 后仍保留在屏幕的中心,如果它是 TRUE那么翻译后需要调整锚视点,使锚视点等于x。

【讨论】:

  • 使得视图的anchorPoint等于x相对于screen?
【解决方案3】:

我想 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
 ];

【讨论】:

  • 第一个问题,是的。而且,我想同时翻译和缩放。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 2012-10-27
相关资源
最近更新 更多