CGAffineTransformScale不适用于零刻度

时间:2014-09-21 21:48:57

标签: ios zoom scale cgaffinetransform cgaffinetransformscale

更新到iOS 8,我注意到了一个有趣的问题。我使用CGAffineTransformScale将图像视图缩放到零,这个想法是它从用户的视图中整齐地消失。这是iOS8的工作,但现在它根本没有。视线瞬间消失;空白!

最初我用过:

CGAffineTransform zoom = CGAffineTransformScale(CGAffineTransformIdentity, 0.0f, 0.0f);
myImageView.transform = zoom;

为什么到目前为止不起作用以及函数何时没有折旧?

2 个答案:

答案 0 :(得分:21)

A CGAffineTransform是一个3x3矩阵,其最右边的列永久设置为(0,0,1) T 。所以它实际上存储了六个值,它们称之为 a,b,c,d,tx, ty 。前四个控制旋转,缩放和倾斜。最后两个控制翻译。

您可能认为从变换T到变换U的动画是一个简单的组件插值问题:T.aU.aT.bU.b等等(我称之为“简单插值”。)

你错了。

好的,请坚持我。这个解释似乎很迂回,但我保证到最后你会明白为什么零刻度会破坏动画。

这是一个我掀起的演示应用程序。它仅在身份变换和160˚旋转之间进行插值(180˚)。

simple interpolation

注意两件事:图像缩小然后扩展,并且它没有均匀的角速度。旋转开始缓慢,加速,然后再次减速。那不是我生涩的手部动作;它使用简单的插值实际上就是这样。

那么这里发生了什么?让我们看看中途的变换(80˚):

80 degrees

文字:
[0.030153692, 0.17101011, -0.17101011, 0.030153692, 0, 0]

80˚的旋转变换应该是什么样的?像这样:
[0.17364822, 0.98480773, -0.98480773, 0.17364822, 0, 0]

正如您可能已经注意到的那样,这些矩阵是相当不同的。仅表示轮换的转换具有多个属性:a*a + b*b == 1a == db == -c。真正的旋转矩阵具有所有这些属性,但简单插值矩阵却没有。具体来说,它的a*a + b*b == .030153695与1相差很远。这意味着它不仅代表旋转,还代表缩放。

这意味着,一般来说,不能只是简单地在两个变换之间进行插值并获得不错的结果。所以系统做了一些更复杂的事情。

核心动画将变换分解为四个部分:旋转角度,比例因子,剪切因子和平移。它插入这些部分,并使用插值来计算动画的中间变换。

“OK”,你说,“但这与零刻度矩阵打破动画有什么关系?”

您可以找到用于分解矩阵in this mathoverflow Q&A的数学运算。请注意,要计算旋转角度和剪切因子,您需要除以矩阵的至少一个分量(答案中的A 11 或A 21 ,{{ 1}}或a中的b)。但是,当您按比例缩放零时,这些组件将变为零。你不能除以零。

因此,当系统尝试分解您的转换时,它会失败,并且它会放弃。

我不是说这是良好的行为,但这是我们的行为。

答案 1 :(得分:8)

所以我所做的就是将缩放比例从零改为小:

CGAffineTransform zoom = CGAffineTransformScale(CGAffineTransformIdentity, 0.001f, 0.001f);
myImageView.transform = zoom;

这很好用。恢复正常。

我对解决方案感到满意,我主要想把它作为解决方案提供给任何需要它的人,但我也会问,为什么会这样?

(请保持友善 - 只是想帮助遇到这个人的人。)