CGAffineTransform缩放和平移 – 在animation之前跳转

我正在努力解决CGAffineTransform缩放和转换问题,当我在已经有转换的视图上的animation块中设置转换时,视图在animation之前跳转了一下。

例:

// somewhere in view did load or during initialization var view = UIView() view.frame = CGRectMake(0,0,100,100) var scale = CGAffineTransformMakeScale(0.8,0.8) var translation = CGAffineTransformMakeTranslation(100,100) var concat = CGAffineTransformConcat(translation, scale) view.transform = transform // called sometime later func buttonPressed() { var secondScale = CGAffineTransformMakeScale(0.6,0.6) var secondTranslation = CGAffineTransformMakeTranslation(150,300) var secondConcat = CGAffineTransformConcat(secondTranslation, secondScale) UIView.animateWithDuration(0.5, animations: { () -> Void in view.transform = secondConcat }) } 

现在当调用buttonPressed()时,在开始animation之前,视图跳转到左上angular大约10个像素。 我只是目睹了一个concat转换这个问题,只使用一个转换转换工作正常。

编辑:由于我已经做了很多关于此事的研究,我想我应该提到,无论是否打开自动布局,都会出现此问题

我遇到了同样的问题,但找不到问题的确切来源。 跳转似乎只出现在非常特定的条件下:如果视图从变换t1animation到变换t2并且两个变换都是比例和翻译的组合(这正是您的情况)。 鉴于以下解决方法,这对我来说没有意义,我认为这是Core Animation中的一个错误。

首先,我尝试使用CATransform3D而不是CGAffineTransform

旧代码:

 var transform = CGAffineTransformIdentity transform = CGAffineTransformScale(transform, 1.1, 1.1) transform = CGAffineTransformTranslate(transform, 10, 10) view.layer.setAffineTransform(transform) 

新代码:

 var transform = CATransform3DIdentity transform = CATransform3DScale(transform, 1.1, 1.1, 1.0) transform = CATransform3DTranslate(transform, 10, 10, 0) view.layer.transform = transform 

新的代码应该等同于旧代码(第四个参数设置为1.00这样在z方向上不存在缩放/平移),实际上它显示的是相同的跳转。 然而,这里是黑魔法:在比例转换中,将z参数更改为与1.0不同的值,如下所示:

 transform = CATransform3DScale(transform, 1.1, 1.1, 1.01) 

这个参数应该没有效果,但是现在跳转了。

🎩✨

问题的根源在于缺乏透视信息。

您可以添加修改3D变换的m34属性的透视信息

 var transform = CATransform3DIdentity transform.m34 = 1.0 / 200 //your own perspective value here transform = CATransform3DScale(transform, 1.1, 1.1, 1.0) transform = CATransform3DTranslate(transform, 10, 10, 0) view.layer.transform = transform 

看起来像苹果UIViewanimation的内部错误。 当Apple在两个值之间插入CGAffineTransform更改以创buildanimation时,应执行以下步骤:

  • 提取翻译,缩放和旋转
  • 从头到尾内插提取的值
  • 为每个插值步骤组装CGAffineTransform

assembly应按以下顺序进行:

  • 翻译
  • 缩放
  • 回转

但看起来像苹果在缩放和旋转后进行翻译。 这个bug应该由苹果修复。

代替CGAffineTransformMakeScale()和CGAffineTransformMakeTranslation(),它们根据CGAffineTransformIdentity(基本上没有变换)创build一个变换,您想要使用CGAffineTransformScale()和CGAffineTransformTranslate()来基于视图的当前变换进行缩放和翻译,转变。