我在步骤中应用变换时遇到了一些意外的,不一致的行为,而不是立即应用它们,我想知道原因。
假设我们有一个标签,我们希望将其翻译到右侧100
和50
,然后向上扩展到原始大小的1.5
倍。所以有两种转变:
并说我们正在尝试两种不同的动画:
在第一个动画中,您可以执行以下操作:
UIView.animate(withDuration: 5, animations: {
label.transform = label.transform.translatedBy(x: 100, y: 50).scaledBy(x: 1.5, y: 1.5)
}, completion: nil)
一切都表现出你的期望。标签同时平滑翻译和缩放。
在第二个动画中:
UIView.animate(withDuration: 5, animations: {
label.transform = label.transform.translatedBy(x: 100, y: 50)
}, completion: { _ in
UIView.animate(withDuration: 5, animations: {
label.transform = label.transform.scaledBy(x: 1.5, y: 1.5)
}, completion: nil)
})
标签正确翻译,然后 boom ,它会意外跳转然后开始缩放。
是什么导致突然,意外的跳跃?通过检查每个变换的矩阵(并行变换和顺序变换),值与预期的值相同。
并行化动画
transform before translate and scale: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0)
translate and scale transform: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0)
transform after translate and scale: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0)
顺序动画
transform before translation: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0)
translation transform: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 100.0, ty: 50.0)
transform after translation: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 100.0, ty: 50.0)
transform before scale: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 100.0, ty: 50.0)
scale transform: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0)
transform after scale: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0)
那是什么导致突然跳跃?
答案 0 :(得分:1)
您需要了解动画在iOS中的运作方式。您的animation
闭包块立即运行,最终值立即分配给对象(这是最重要的点之一
很多人忘了)。所有animation
块都会使它看起来花费那么多时间。让我详细说明一下。
let x = UIView()
x.alpha = 0
//At this point, alpha is 0
UIView.animate(withDuration: 5, animations: {
x.alpha = 1
}, completion: nil)
//At this point, alpha is 1 right away. But the animation itself will take 5 seconds
考虑到这一点,让我们看看你发布的第二个例子
UIView.animate(withDuration: 5, animations: {
label.transform = label.transform.translatedBy(x: 100, y: 50)
}, completion: { _ in
UIView.animate(withDuration: 5, animations: {
label.transform = label.transform.scaledBy(x: 1.5, y: 1.5)
}, completion: nil)
})
第一个动画会立即运行并翻译您的视图。移动到那里只需要5秒,但你的视图是x& y值已经改变。完成后,你缩放它会导致一种奇怪的行为。