ios - 为什么分步应用的 CGAffineTransform 与一次应用的行为不同?

标签 ios swift animation cgaffinetransform cgaffinetransformscale

在分步应用转换而不是一次应用转换时,我看到了一些意想不到的、不一致的行为,我想知道为什么。

假设我们有一个标签,我们想将其转换为正确的 100 和向下的 50,然后放大到 1.5 倍原始大小。所以有两个转换:

  1. 翻译
  2. 规模

假设我们正在试验两种不同的动画:

  1. 并行执行平移和缩放
  2. 执行翻译,然后按顺序执行缩放

在第一个动画中你可能会做这样的事情:

UIView.animate(withDuration: 5, animations: {
    label.transform = label.transform.translatedBy(x: 100, y: 50).scaledBy(x: 1.5, y: 1.5)
}, completion: nil)

First Animation

一切都如您所愿。标签同时平滑地平移和缩放。

在第二个动画中:

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)
})

Animation 2

标签翻译正确,然后,它意外跳跃,然后开始缩放。

是什么导致了突然的、意想不到的跳跃?通过检查每个变换(并行化和顺序变换)的矩阵,值是相同的,正如预期的那样。

并行动画

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)

那么是什么导致突然跳跃呢?

最佳答案

您需要了解动画在 iOS 中的工作原理。您的 animation 闭包 block 立即运行,最终值立即分配给对象(这是最重要的一点之一 很多人忘记了)。 animation block 所做的就是让它看起来花费那么多时间。让我用一个例子来详细说明。

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)
})

第一个动画运行并立即转换您的 View 。移动到那里只需要 5 秒,但 View 的 x 和 y 值已经改变。完成后,您对其进行缩放,导致出现奇怪的行为。

关于ios - 为什么分步应用的 CGAffineTransform 与一次应用的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47567495/

相关文章:

ios - 有没有办法以编程方式将 View 从一个按钮居中到另一个按钮?

objective-c - 在 iOS 的 Objective-C 中创建带有完成 block 的可中断动画?

jQuery Animate - 不会对绝对 DIV 进行动画处理

CSS 在打开和关闭时淡入淡出不同的字母

swift - 在 Swift 4.2 中是否可以使用特定类型的 rawValue 将默认扩展写入枚举?

ios - 如何在Navbar上更改这些颜色?

ios - UICollectionView设置默认位置

ios - 没有在应用商店发布应用,如何为我的 iOS 应用推送更新?

ios - UINavigationController "pushViewController:animated"的完成处理程序?

ios - FileManager MoveItem 回调 - Swift