swift - 链接 UIView 动画

nas*_*sia 3 core-animation calayer uiviewanimation swift

我想UIImageView通过以下步骤来制作动画:

  1. 缩放2倍
  2. 缩放图像移动

所以我正在尝试这样:

UIView.animate(withDuration: 0.5, animations: {
   self.imageView.transform = CGAffineTransform(scaleX: 2, y: 2)                        
}) { _ in                        
   UIView.animate(withDuration: 1.0, animations: {
        self.imageView.transform = CGAffineTransform(translationX: -50, y: -50)
                        
   }) { _ in

        //other steps
   }
 }
Run Code Online (Sandbox Code Playgroud)

但结果是移动之前imageView又恢复到之前的大小,然后再移动。如何移动鳞片 view

我也尝试过更改块anchorPoint内的animate图层但没有成功

也许有更简单的方法来实现我的目标:能够缩小图像,然后聚焦在 3 个自定义点,然后放大到初始尺寸。

Rob*_*Rob 7

有以下几种方法:

\n
    \n
  1. 一种方法是将动画的开始放入前一个动画的完成处理程序中:

    \n
    UIView.animate(withDuration: 1) { \n    \xe2\x80\xa6\n} completion: { _ in\n    UIView.animate(withDuration: 2) { \n        \xe2\x80\xa6\n    } completion: {  _ in \n        UIView.animate(withDuration: 1) { \n            \xe2\x80\xa6\n        } completion: {  _ in \n            \xe2\x80\xa6\n        }\n    }\n}\n
    Run Code Online (Sandbox Code Playgroud)\n
  2. \n
  3. 如果您想避免嵌套动画塔(每个动画都在前一个动画的完成处理程序中),您可以使用关键帧动画,例如,这是一个包含三个独立关键帧的五秒动画,每个关键帧的持续时间为动画的三分之一。总计,并相应设置其开始时间:

    \n
    UIView.animateKeyframes(withDuration: 5, delay: 0) { \n    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1 / 3) {\n        \xe2\x80\xa6\n    }\n\n    UIView.addKeyframe(withRelativeStartTime: 1 / 3, relativeDuration: 1 / 3) {\n        \xe2\x80\xa6\n    }\n\n    UIView.addKeyframe(withRelativeStartTime: 2 / 3, relativeDuration: 1 / 3) {\n        \xe2\x80\xa6\n    }\n}\n
    Run Code Online (Sandbox Code Playgroud)\n

    以上适用于 Swift 5.3 及更高版本。对于早期版本,请参阅此答案的先前修订版

    \n
  4. \n
  5. 如今,我们可能会自然而然地寻求 Swift 并发(因为它擅长管理异步任务之间的依赖关系),并且一般来说,Swift 非常擅长使用async完成处理程序参数渲染旧 Objective-C API 的版本(请参阅SE-0297:与 Objective 的并发互操作性) -C:异步完成处理程序方法)。但UIView动画功能还没有优雅地映射到async再现。因此,我们可以使用延续来编写我们自己的动画 APIasync再现:UIView

    \n
    extension UIView {\n    class func animate(\n        for duration: Duration,\n        delay: Duration = .zero,\n        options: UIView.AnimationOptions = [],\n        animations: @MainActor @Sendable @escaping () -> Void\n    ) async {\n        await withCheckedContinuation { continuation in\n            UIView.animate(\n                withDuration: duration.timeInterval,\n                delay: delay.timeInterval,\n                options: options,\n                animations: animations\n            ) { _ in\n                continuation.resume()\n            }\n        }\n    }\n}\n\nextension Duration {\n    var timeInterval: TimeInterval {\n        let (wholeSeconds, attoseconds) = components\n        return TimeInterval(wholeSeconds) + TimeInterval(attoseconds) / 1e18\n    }\n}\n
    Run Code Online (Sandbox Code Playgroud)\n

    然后,从异步上下文中,您可以使用 Swift 并发:

    \n
    await UIView.animate(for: .seconds(1), delay: .seconds(1.5)) {\n    \xe2\x80\xa6\n}\nawait UIView.animate(for: .seconds(1)) {\n    \xe2\x80\xa6\n}\nawait UIView.animate(for: .seconds(1)) {\n    \xe2\x80\xa6\n}\n
    Run Code Online (Sandbox Code Playgroud)\n
  6. \n
\n