swift -链接UIView动画

jjhzyzn0  于 11个月前  发布在  Swift
关注(0)|答案(2)|浏览(113)

我想用这些步骤动画我的UIImageView
1.规模2倍
1.缩放图像移动
所以我试着这样做:

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

字符串
但结果是,在移动imageView回到以前的大小,然后移动。如何移动缩放view
另外,我尝试在animate块中更改层的anchorPoint,但没有成功
也许有更简单的方法来实现我的目标:能够缩小图像,然后在3个自定义点聚焦,然后放大到初始大小。

nwwlzxa7

nwwlzxa71#

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

UIView.animate(withDuration: 1) { 
    …
} completion: { _ in
    UIView.animate(withDuration: 2) { 
        …
    } completion: {  _ in 
        UIView.animate(withDuration: 1) { 
            …
        } completion: {  _ in 
            …
        }
    }
}

字符串
1.如果你想避免一堆嵌套动画(每个都在前一个的完成处理程序中),你可以使用关键帧动画,例如,这是一个五秒的动画,有三个单独的关键帧,每个关键帧的持续时间是总持续时间的三分之一,并且其开始时间相应地设置:

UIView.animateKeyframes(withDuration: 5, delay: 0) { 
    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1 / 3) {
        …
    }

    UIView.addKeyframe(withRelativeStartTime: 1 / 3, relativeDuration: 1 / 3) {
        …
    }

    UIView.addKeyframe(withRelativeStartTime: 2 / 3, relativeDuration: 1 / 3) {
        …
    }
}


以上是针对Swift 5.3及更高版本的。对于早期版本,请参阅此答案的previous revision
1.如今,我们可能会自然而然地使用Swift并发(因为它擅长管理异步任务之间的依赖关系),一般来说,Swift非常擅长使用完成处理程序参数渲染旧的X1 m0n1x API(请参见SE-0297:与EST-C的并发互操作性:但是UIView动画函数(目前还没有)优雅地Map到async渲染。所以我们可以使用continuation来编写我们自己的UIView动画API的async渲染:

extension UIView {
    class func animate(
        for duration: Duration,
        delay: Duration = .zero,
        options: UIView.AnimationOptions = [],
        animations: @MainActor @Sendable @escaping () -> Void
    ) async {
        await withCheckedContinuation { continuation in
            UIView.animate(
                withDuration: duration.timeInterval,
                delay: delay.timeInterval,
                options: options,
                animations: animations
            ) { _ in
                continuation.resume()
            }
        }
    }
}

extension Duration {
    var timeInterval: TimeInterval {
        let (wholeSeconds, attoseconds) = components
        return TimeInterval(wholeSeconds) + TimeInterval(attoseconds) / 1e18
    }
}


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

await UIView.animate(for: .seconds(1), delay: .seconds(1.5)) {
    …
}
await UIView.animate(for: .seconds(1)) {
    …
}
await UIView.animate(for: .seconds(1)) {
    …
}

6uxekuva

6uxekuva2#

第一个问题:由于您将transform分配给一个新的,而不保留旧的配置,因此在第二个动画中,您的视图将转换为默认比例(1,1)。您所需要的只是将transform分配给一个新的,其中包含所有旧的配置以及您想要的新配置。

UIView.animate(withDuration: 0.5, animations: {
  self.button.transform = self.button.transform.scaledBy(x: 2, y: 2)
}) { _ in
  UIView.animate(withDuration: 1.0, animations: {
    self.button.transform = self.button.transform.translatedBy(x: -50, y: -50)
  }) { _ in
    
  }
}

字符串
如果使用animateKeyframes,效果会更好

相关问题