CGAffineTransformScale不能使用零刻度

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

所以原来我用:

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

为什么到现在为止,这个function还没有起作用呢?

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

你可能认为从变换T到变换Uanimation是一个简单的分量插值问题: TaUaTbUb等(我将称之为“简单插值”)。

你会错的。

好的,坚持我在这里。 这个解释看起来似乎是迂回的,但我承诺到最后你会明白为什么零比例尺会破坏animation。

这是一个我掀起的演示程序。 它简单地插入在身份转换和160˚旋转( 不是 180˚)之间。

简单的插值

注意两件事:图像收缩然后展开,并且没有均匀的angular速度。 旋转开始缓慢,加速,然后再减慢。 那不是我生涩的手势。 它使用简单的插值performance得如此。

那么这里发生了什么? 我们来看一下中间的转换(在80˚):

80度

在文本中:
[0.030153692, 0.17101011, -0.17101011, 0.030153692, 0, 0]

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

正如你可能已经注意到的那样,这些matrix是相当不同的。 仅表示旋转的变换具有几个属性: a*a + b*b == 1a == db == -c 。 真正的旋转matrix具有所有这些属性,但是简单插值的matrix不会。 具体而言,它的a*a + b*b == .030153695 ,与1相差很远。这意味着它不仅表示旋转,而且表示缩放。

这意味着,一般来说,你不能简单地插入两个变换之间,并得到体面的结果。 所以系统做了一些更复杂的事情。

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

“OK”,你是说,“但这与零级matrix打破animation有什么关系?

你可以在这个mathoverflow Q&A中find分解matrix的math。 请注意,要计算旋转angular度和剪切因子,您需要除以matrix的至less一个分量(该答案中的A 11或A 21CGAffineTransform ab )。 但是,当您缩放为零的因子时,这些组件将变为零。 你不能被零除。

所以当系统试图分解你的变换时,它会失败,而且会放弃。

我不是说这是行为,而是我们所处的行为。

所以我所做的是改变缩放比例从零到小:

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

这工作很好。 恢复正常。

我对这个解决scheme感到满意,我主要感兴趣的是将这个解决scheme作为解决其他人需要的解决scheme,但是我也会问,这是为什么?

(请保持好心态 – 试图帮助任何碰到这个人的人。)