我正在尝试制作一个按钮1.0
->的简单比例动画;1.4
,重复3次,然后停止,但我在实际设备上遇到了故障。
下面的代码在模拟器上运行得很顺利,但在真实的设备上(iPhone 12 Pro和iOS 16(,它会出现故障,我可以看到动画完成后跳转到缩放1.4
,然后在完成后跳转至缩放1.0
,我设置了transform = .identity
。
我怀疑UIView.modifyAnimations
,但现在不推荐使用的UIView.setAnimationRepeatCount(3)
也会出现同样的问题。
以下是真实设备上出现故障的视频:https://i.imgur.com/x1LJ9Ox.mp4
UIView.animate(withDuration: 0.5, delay: 0, animations: {
UIView.modifyAnimations(withRepeatCount: 3, autoreverses: true) {
self.titleButton.transform = CGAffineTransformMakeScale(1.4, 1.4)
// self.titleButton.layoutIfNeeded() // doesn't change anything
}
}, completion: { _ in
self.titleButton.transform = .identity
})
我已经在我的iphone 13 iOS 16上进行了测试,它像你上面说的那样出现了故障。
也许我错了或误解了什么,但modifyAnimations(withRepeatCount:autoreverses:animations:)
中似乎有什么在改变。
在模拟器中,modifyAnimations
中的动画完成后,它立即转到completion
。如果在completion
中不对视图执行任何操作,它将返回到CGAffineTransformMakeScale(1.4, 1.4)
。但是,如果视图中有transform
,它将转向transform
。
但在实际设备中,在modifyAnimations
中的动画完成后,视图将立即返回到动画的最终版本,这里是CGAffineTransformMakeScale(1.4, 1.4)
(模拟器没有这个步骤(,然后转到completion
。这导致了你说的故障。
我有一个解决这种情况的方法
UIView.animate(withDuration: 0.5, animations: {
// stop at the half of the final repeat means no autoreverses accur at the end
UIView.modifyAnimations(withRepeatCount: 2.5, autoreverses: true) {
self.secondView.transform = CGAffineTransformMakeScale(1.4, 1.4)
}
}, completion: { _ in
// make final scale back here
UIView.animate(withDuration: 0.5, animations: {
self.secondView.transform = .identity
})
})
看起来iOS 16正在更新导致故障的动画后的transform 1事件循环。解决这个问题的一种方法是在动画结束时使用关键帧动画(我在这个答案中找到了(并添加代码重复3次,将比例保持在1.0:
UIView.animateKeyframes(withDuration: 1, delay: 0, options: [], animations: {
UIView.modifyAnimations(withRepeatCount: 3, autoreverses: false) {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) {
self.titleButton.transform = CGAffineTransformMakeScale(1.4, 1.4)
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
self.titleButton.transform = .identity
}
}
}) { (isFinished) in
}