Swift 3 动画问题
Posted
技术标签:
【中文标题】Swift 3 动画问题【英文标题】:Swift 3 animation issue 【发布时间】:2016-10-28 23:29:54 【问题描述】:我正在实现简单地为颜色设置动画的进度视图。
除了按形状填充并使其闪烁的“strokeEnd”动画之外,一切都运行良好。
视频resource
代码示例:
class MaterialCircularProgressView: UIView
let circularLayer = CAShapeLayer()
let googleColors = [
UIColor(red:0.282, green:0.522, blue:0.929, alpha:1),
UIColor(red:0.859, green:0.196, blue:0.212, alpha:1),
UIColor(red:0.957, green:0.761, blue:0.051, alpha:1),
UIColor(red:0.235, green:0.729, blue:0.329, alpha:1)
]
let inAnimation: CAAnimation =
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
return animation
()
let outAnimation: CAAnimation =
let animation = CABasicAnimation(keyPath: "strokeStart")
animation.beginTime = 0.5
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
return animation
()
let rotationAnimation: CAAnimation =
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.fromValue = 0.0
animation.toValue = 2 * M_PI
animation.duration = 2.0
animation.repeatCount = MAXFLOAT
return animation
()
var colorIndex : Int = 0
override init(frame: CGRect)
super.init(frame: frame)
circularLayer.lineWidth = 4.0
circularLayer.fillColor = nil
layer.addSublayer(circularLayer)
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func layoutSubviews()
super.layoutSubviews()
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = min(bounds.width, bounds.height) / 2 - circularLayer.lineWidth / 2
let arcPath = UIBezierPath(arcCenter: CGPoint.zero, radius: radius, startAngle: CGFloat(M_PI_2), endAngle: CGFloat(M_PI_2 + (2 * M_PI)), clockwise: true)
circularLayer.position = center
circularLayer.path = arcPath.cgPath
animateProgressView()
circularLayer.add(rotationAnimation, forKey: "rotateAnimation")
func animateProgressView()
circularLayer.removeAnimation(forKey: "strokeAnimation")
circularLayer.strokeColor = googleColors[colorIndex].cgColor
let strokeAnimationGroup = CAAnimationGroup()
strokeAnimationGroup.duration = 1.0 + outAnimation.beginTime
strokeAnimationGroup.repeatCount = 1
strokeAnimationGroup.animations = [inAnimation, outAnimation]
strokeAnimationGroup.delegate = self
circularLayer.add(strokeAnimationGroup, forKey: "strokeAnimation")
colorIndex += 1;
colorIndex = colorIndex % googleColors.count;
extension MaterialCircularProgressView: CAAnimationDelegate
override func animationDidStop(_ anim: CAAnimation, finished flag: Bool)
if(flag)
animateProgressView()
【问题讨论】:
【参考方案1】:您可以通过在初始化程序中将 strokeStart 设置为 outAnimation
的最终值来解决闪烁问题:
circularLayer.strokeStart = 1.0
原因是CAPropertyAnimation
动画属性的实际值不会自动设置为动画的toValue
,因此它会恢复为原始值,在您的情况下为0.0
。这就是为什么会出现一段时间的完整圆圈。
但是在下一个圆圈出现之前会有延迟,不确定这是您的意图还是要修复的其他错误。
【讨论】:
以上是关于Swift 3 动画问题的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 iOS 10 - 将“滑动解锁”动画应用于标签
UIButtons 在动画期间没有响应 - iOS Swift 3