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,tx和ty 。 前四个控制旋转,缩放和倾斜。 最后两个控件翻译。
你可能认为从变换T
到变换U
animation是一个简单的分量插值问题: Ta
到Ua
, Tb
到Ub
等(我将称之为“简单插值”)。
你会错的。
好的,坚持我在这里。 这个解释看起来似乎是迂回的,但我承诺到最后你会明白为什么零比例尺会破坏animation。
这是一个我掀起的演示程序。 它简单地插入在身份转换和160˚旋转( 不是 180˚)之间。
注意两件事:图像收缩然后展开,并且没有均匀的angular速度。 旋转开始缓慢,加速,然后再减慢。 那不是我生涩的手势。 它使用简单的插值performance得如此。
那么这里发生了什么? 我们来看一下中间的转换(在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 == 1
, a == d
和b == -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 21 , CGAffineTransform
a
或b
)。 但是,当您缩放为零的因子时,这些组件将变为零。 你不能被零除。
所以当系统试图分解你的变换时,它会失败,而且会放弃。
我不是说这是好行为,而是我们所处的行为。
所以我所做的是改变缩放比例从零到小:
CGAffineTransform zoom = CGAffineTransformScale(CGAffineTransformIdentity, 0.001f, 0.001f); myImageView.transform = zoom;
这工作很好。 恢复正常。
我对这个解决scheme感到满意,我主要感兴趣的是将这个解决scheme作为解决其他人需要的解决scheme,但是我也会问,这是为什么?
(请保持好心态 – 试图帮助任何碰到这个人的人。)