我正在尝试为UIButton
制作非常基本的动画。目标是将图层旋转180度。这是我的动画代码,从beginTrackingWithTouch
调用:
private func rotateButton() {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotationAnimation.timingFunction = CAMediaTimingFunction(name: "easeIn")
rotationAnimation.toValue = M_PI
rotationAnimation.duration = CollapseButton.kCollapseButtonAnimationDuration
rotationAnimation.repeatCount = 1
rotationAnimation.cumulative = true
layer.addAnimation(rotationAnimation, forKey: "rotationAnimation")
}
现在我想添加折叠视图动画时,点击这个按钮。在我的VC:
__weak __typeof(self) weakSelf = self;
[UIView animateWithDuration:CollapseButton.kCollapseButtonAnimationDuration animations:^{
CGRect currentFrame = weakSelf.frame;
currentFrame.size.height = 20;
weakSelf.frame = currentFrame;
}];
我有两个问题:
按钮完成动画后重置图层位置。所以,如果箭头显示顶部,它动画显示向下,并最终重置到顶部。如何保持图层方向?
可以看到动画持续时间和计时功能是相同的。因为我不能理解UIView动画变慢的原因。什么好主意吗?
核心动画很奇怪。该动画创建了一个"表示层",该层生成正在制作动画的更改的外观,但实际上并不更改所讨论的属性。
为了让你的动画在结束状态下结束,你应该设置fromValue(在开始设置时)和toValue,然后在提交动画后将属性设置为它的结束值:
private func rotateButton() {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotationAnimation.timingFunction = CAMediaTimingFunction(name: "easeIn")
rotationAnimation.fromValue = 0.0 //<<--- NEW CODE
rotationAnimation.toValue = M_PI
rotationAnimation.duration = CollapseButton.kCollapseButtonAnimationDuration
rotationAnimation.repeatCount = 1
rotationAnimation.cumulative = true
layer.addAnimation(rotationAnimation, forKey: "rotationAnimation")
layer.transform = CATransformMakeRotation(M_PI) //<<--- NEW CODE
}
你也可以将动画的removeWhenFinished
属性设置为true,但这有其他的复杂性。
顺便说一句,您不应该尝试操作具有非恒等转换的视图的框架。相反,在视图的transform中设置缩放。
我不知道为什么这两个动画花了不同的时间。我注意到你将CAAnimation的计时功能设置为easeIn
,但将UIView的计时功能设置为默认值(ease-in, ease-out)。这将创建看起来不一样的动画。你可能应该设置你的视图动画使用easeIn
计时。(要做到这一点,你需要使用较长的形式animateWithDuration:delay:options:animations:completion:
)