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转换这个问题,只使用一个转换转换工作正常。
编辑:由于我已经做了很多关于此事的研究,我想我应该提到,无论是否打开自动布局,都会出现此问题
我遇到了同样的问题,但找不到问题的确切来源。 跳转似乎只出现在非常特定的条件下:如果视图从变换t1
animation到变换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.0
或0
这样在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()来基于视图的当前变换进行缩放和翻译,转变。