我正在使用关键帧为标签创建一个简单的从左到右的动画,但是当动画重复时,会忽略延迟。
第一次执行时,3秒的延迟有效,但是当动画重复时,忽略延迟。这会导致动画在结束后立即重新启动。
UIView.animateKeyframes(withDuration: 10, delay: 3, options: [.calculationModePaced, .repeat], animations: {
let xDist = self.Label_ArtistAlbum2.frame.origin.x
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.1, animations: {
self.Label_ArtistAlbum2.frame.origin.x = self.Label_ArtistAlbum2.frame.origin.x - (xDist * 0.1)
})
UIView.addKeyframe(withRelativeStartTime: 0.9, relativeDuration: 0.1, animations: {
self.Label_ArtistAlbum2.frame.origin.x = 0
})
}, completion: nil)
我已经尝试在最后添加一个额外的关键帧,但即使更改时间也没有效果:
UIView.animateKeyframes(withDuration: 10, delay: 3, options: [.calculationModePaced, .repeat], animations: {
let xDist = self.Label_ArtistAlbum2.frame.origin.x
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.1, animations: {
self.Label_ArtistAlbum2.frame.origin.x = self.Label_ArtistAlbum2.frame.origin.x - (xDist * 0.1)
})
UIView.addKeyframe(withRelativeStartTime: 0.1, relativeDuration: 0.7, animations: {
self.Label_ArtistAlbum2.frame.origin.x = 0
})
//attempted pause - does not appear to work perhaps since the position is unchanged?
UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 0.2, animations: {
self.Label_ArtistAlbum2.frame.origin.x = 0
})
}, completion: nil)
如果延迟不会与动画的其余部分一起重复,如何在整个动画重复之前创建暂停?
答案 0 :(得分:1)
我已经在这个问题上做了很多测试,并找到了我认为的问题。
我认为曲线的动画选项是我的问题。 在我的情况下选择
<强> calculationModePaced 强>
具有重新计算我的关键帧参数的效果,并且不保证除了开头和结尾之外都会击中它们中的任何一个。所有中间关键帧都成为“建议”。 你不能在最后创建一个暂停,因为关键帧在重新计算时被“消耗”,并且不能独立存在。
我改为calculateModeLinear并获得了我期望的关键帧,以及暂停。 但是,它和我想的一样顺畅,所以我不得不继续修补......
Apple的文档在这里 - 它们是描述性的,但可以真正使用一些图形和/或示例: https://developer.apple.com/reference/uikit/uiview?language=swift
可在此处找到曲线的良好图表:https://www.shinobicontrols.com/blog/ios7-day-by-day-day-11-uiview-key-frame-animations
答案 1 :(得分:0)
我在为加载视图设置动画方面遇到了类似的问题。我这样解决了:
我为动画中的步骤创建了一个枚举
private enum TriangleToAnimate {
case one
case two
case three
case pause
}
我有我的变量
private var triangleViewToFireCount = TriangleToAnimate.one
var triangle1View : TriangleView
var triangle2View : TriangleView
var triangle3View : TriangleView
我启动一个计时器来运行每个动画
override init(frame: CGRect) {
Timer.scheduledTimer(timeInterval: 0.33, target: self, selector: #selector(LoadingView.timerFire), userInfo: nil, repeats: true)
}
对于选择器我有一个火法。在方法中,我为每个枚举案件设置了一个开关
func timerFire(){
let anim = createAnimation()
switch triangleViewToFireCount {
case .one:
triangle1View.layer.add(anim, forKey: "transform")
triangleViewToFireCount = .two
case .two:
triangle2View.layer.add(anim, forKey: "transform")
triangleViewToFireCount = .three
case .three:
triangle3View.layer.add(anim, forKey: "transform")
triangleViewToFireCount = .pause
default:
triangleViewToFireCount = .one
}
}
这是我将动画创建为关键帧的代码
func createAnimation() -> CAKeyframeAnimation{
let tr = CATransform3DIdentity
let orignalScale = CATransform3DScale(tr, 1, 1, 1)
let doubleScale = CATransform3DScale(tr, 2, 2, 1)
let keyAn = CAKeyframeAnimation(keyPath: "transform")
keyAn.keyTimes = [0, 0.1, 0.6]
keyAn.duration = 1
keyAn.values = [orignalScale,doubleScale,orignalScale]
keyAn.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
return keyAn
}