Alb*_*erg 7 core-animation cakeyframeanimation ios swift swift3
我很难理解为什么动画不能像预期的那样工作.我在做什么是这样的:
UIBezierPath使用圆弧创建一个沿此路径移动Label并为路径描边设置动画.
//Start Point is -.pi /2 to let the Arc start at the top.
//self.progress = Value between 0.0 and 1.0
let path : UIBezierPath = UIBezierPath.init(arcCenter: CGPoint.init(x: self.bounds.width * 0.5, y: self.bounds.height * 0.5),
radius: self.bounds.width * 0.5, startAngle: -.pi / 2, endAngle: (2 * self.progress * .pi) - (.pi / 2), clockwise: true)
return path
Run Code Online (Sandbox Code Playgroud)将此路径添加到 CAShapeLayer
circlePathLayer.frame = bounds
circlePathLayer.path = self.path.cgPath
circlePathLayer.strokeStart = 0
circlePathLayer.strokeEnd = 1
Run Code Online (Sandbox Code Playgroud)使用a为strokeEnd属性设置动画 CABasicAnimation
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.repeatCount = HUGE
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = self.animationDuration
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeBoth
Run Code Online (Sandbox Code Playgroud)使用a为我的标签的position属性设置动画 CAKeyFrameAnimation
let animationScore = CAKeyframeAnimation(keyPath: "position")
//some things I tried to fix
//animationScore.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.250, 0.250, 0.750, 0.750)]
//animationScore.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)
animationScore.path = self.path.cgPath
animationScore.duration = self.animationDuration
animationScore.isRemovedOnCompletion = false
animationScore.fillMode = kCAFillModeBoth
animationScore.repeatCount = HUGE
Run Code Online (Sandbox Code Playgroud)将我的动画添加到图层和标签
self.circlePathLayer.add(animation, forKey: nil)
self.scoreLabel.layer.add(animationScore, forKey: nil)
Run Code Online (Sandbox Code Playgroud)我的问题:对于大于0.75的ProgressValues,我的标签没有以线速度移动.值大于0.75表示我的弧大于PI.对于小于0.75的值,我的动画工作正常,标签和strokeend具有相同的速度并且彼此重叠.
请忽略此gif中标签中的100%,我的进度值为0.76.
你看到我的标签在我的四分之三圈后减慢了.
我希望有一个人可以帮助我.非常感谢
关键帧动画引入了不必要的复杂性.只需围绕中心旋转标签,其持续时间与形状图层的笔触动画相同:
(我很抱歉我的动画从底部开始,而不是顶部,但是当我编写代码时我没有看你的问题,现在我懒得改变它!)
那么,这是怎么做到的?它是三个动画,都具有相同的持续时间:
形状图层strokeEnd,就像你的动画一样.
穿过圆心的"手臂",标签作为一端的子层(使标签出现在圆的半径处).手臂做旋转变换动画.
标签在相反方向上执行旋转变换动画.如果没有,它将与其超级层一起旋转.(想想摩天轮如何工作;你的椅子在手臂的末端,但它相对于地球保持直立.)
这是整个动画代码:
let anim = CABasicAnimation(keyPath: "transform.rotation.z")
anim.fromValue = 0
anim.toValue = 5
anim.duration = 10
self.arm.layer.add(anim, forKey:nil)
let anim2 = CABasicAnimation(keyPath: "transform.rotation.z")
anim2.fromValue = 0
anim2.toValue = -5
anim2.duration = 10
self.lab.layer.add(anim2, forKey:nil)
let anim3 = CABasicAnimation(keyPath: "strokeEnd")
anim3.fromValue = 0
anim3.toValue = 1
anim3.duration = 10
self.shape.add(anim3, forKey:nil)
Run Code Online (Sandbox Code Playgroud)