我正在制作动画,并且我有5个不同的UIViewPropertyAnimatior实例,并且这些动画师中的每个动画师都有 sub-animations ,它们可能开始得早或结束得早。
这使得很难使用animator.addAnimations()
,因为在那里您只能控制延迟。因此,我改为使用UIView.animateKeyframes()
根据WWDC 2017,这是首选方法。 (如果您有好奇心,请跳到27:10)
问题是,当动画反转时,总是有一个View变成越野车,而我真的不知道该怎么做。
以下是该错误的直观展示:
注意标签如何在反转的动画上没有动画。
这是我的UIViewPropertyAnimator代码:
return UIViewPropertyAnimator(duration: totalDuration, curve: .linear, animations: {
UIView.animateKeyframes(withDuration: 0.0, delay: 0.0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: translationDelay , relativeDuration: translationDuration, animations: {
self.firstScreen.transform = firstScreenTranslation
self.secondScreen.transform = secondScreenTranslation
self.map.transform = secondScreenTranslation
self.greenPinsView.transform = secondScreenTranslation
})
UIView.addKeyframe(withRelativeStartTime: overScalePinsDelay, relativeDuration: overScalePinsDuration, animations: {
let scale = CGAffineTransform(scaleX: overScalePinsValue, y: overScalePinsValue)
self.greenPinsAll.forEach {
let (key, value) = $0
var positionTrans = CGAffineTransform()
if isReversed {
positionTrans = .identity
}
else {
if TutorialKeyFrames.coloredPinsStart.keys.contains(key) {
let point = TutorialKeyFrames.coloredPinsStart[key]!
positionTrans = CGAffineTransform(translationX: point.x * self.pinSizeValue, y: point.y * self.pinSizeValue)
}
}
value.transform = scale.concatenating(positionTrans)
}
})
UIView.addKeyframe(withRelativeStartTime: scalePinsDelay, relativeDuration: scalePinsDuration, animations: {
let scale = CGAffineTransform(scaleX: scalePinsValue, y: scalePinsValue)
self.greenPinsAll.forEach {
let (key, value) = $0
var positionTrans = CGAffineTransform()
if isReversed {
positionTrans = .identity
}
else {
if TutorialKeyFrames.coloredPinsStart.keys.contains(key) {
let point = TutorialKeyFrames.coloredPinsStart[key]!
positionTrans = CGAffineTransform(translationX: point.x * self.pinSizeValue, y: point.y * self.pinSizeValue)
}
}
value.transform = scale.concatenating(positionTrans)
}
})
UIView.addKeyframe(withRelativeStartTime: glassYPosDelay, relativeDuration: glassYPosDuration, animations: {
self.magnifyingGlass.transform = glassYPosValue
})
UIView.addKeyframe(withRelativeStartTime: glassOpacityDelay, relativeDuration: glassOpacityDuration, animations: {
self.magnifyingGlass.alpha = glassOpacityValue
})
})
})
最奇怪的部分是,如果我从动画中删除了最后两个关键帧(如下所示),它将重新开始工作。
UIView.addKeyframe(withRelativeStartTime: glassYPosDelay, relativeDuration: glassYPosDuration, animations: {
self.magnifyingGlass.transform = glassYPosValue
})
UIView.addKeyframe(withRelativeStartTime: glassOpacityDelay, relativeDuration: glassOpacityDuration, animations: {
self.magnifyingGlass.alpha = glassOpacityValue
})
它已经使我抓狂了一个多星期了。这就是为什么我认为这是错误的原因:
首先,我100%确定所有视图都具有相同的约束和相同的简单设置功能。</ p>
第二,请注意变换的变化发生在第一个关键帧中:
UIView.addKeyframe(withRelativeStartTime: translationDelay , relativeDuration: translationDuration, animations: {
self.firstScreen.transform = firstScreenTranslation
//Second Screen is the bugged UIView
self.secondScreen.transform = secondScreenTranslation
self.map.transform = secondScreenTranslation
self.greenPinsView.transform = secondScreenTranslation
})
您可以清楚地看到self.secondScreen, self.map
和self.greenPinsView
都将变换更改为相同的值(secondScreenTranslation
)。
在gif中,您可以清楚地看到self.map
在移动,而self.secondScreen
似乎卡住了。
(我也可以确认self.greenPinsView
也在移动。)
另外一个笔记:在gif上,您只能看到一个UIViewPropertyAnimator
实例的实际应用。我说我有5个。是的。我还有5个动画师,其中发生相同的错误。 它始终是包含UILabels的UIView 。这是否可能是因为UILabel不可动画或其他原因?
很抱歉,我的解释很长,我感到很无助。希望得到您的帮助,否则我打算报告此情况。