【发布时间】:2016-05-26 19:07:40
【问题描述】:
全部!
我使用CoreGraphics 创建了一个循环进度视图,其外观和更新如下:
该类是一个UIView 类,它有一个名为“progress”的变量,用于确定圆圈的填充量。
效果很好,但我希望能够对进度变量的更改进行动画处理,以使条形图平滑地动画化。
我从无数示例中读到,我需要一个 CALayer 类以及我创建的 View 类,但是它根本没有动画。
两个问题:
- 我可以保留我在
CoreGraphics中绘制的图形,还是需要以某种方式在CALayer中重新绘制它? -
我当前(尝试的)解决方案在以下位置崩溃:
anim.fromValue = pres.progress。怎么了?class CircleProgressView: UIView { @IBInspectable var backFillColor: UIColor = UIColor.blueColor() @IBInspectable var fillColor: UIColor = UIColor.greenColor() @IBInspectable var strokeColor: UIColor = UIColor.greenColor() dynamic var progress: CGFloat = 0.00 { didSet { self.layer.setValue(progress, forKey: "progress") } } var distToDestination: CGFloat = 10.0 @IBInspectable var arcWidth: CGFloat = 20 @IBInspectable var outlineWidth: CGFloat = 5 override class func layerClass() -> AnyClass { return CircleProgressLayer.self } override func drawRect(rect: CGRect) { var fillColor = self.fillColor if distToDestination < 3.0 { fillColor = UIColor.greenColor() } else { fillColor = self.fillColor } //Drawing the inside of the container //Drawing in the container let center = CGPoint(x:bounds.width/2, y: bounds.height/2) let radius: CGFloat = max(bounds.width, bounds.height) - 10 let startAngle: CGFloat = 3 * π / 2 let endAngle: CGFloat = 3 * π / 2 + 2 * π let path = UIBezierPath(arcCenter: center, radius: radius/2 - arcWidth/2, startAngle: startAngle, endAngle: endAngle, clockwise: true) path.lineWidth = arcWidth backFillColor.setStroke() path.stroke() let fill = UIColor.blueColor().colorWithAlphaComponent(0.15) fill.setFill() path.fill() //Drawing the fill path. Same process let fillAngleLength = (π) * progress let fillStartAngle = 3 * π / 2 - fillAngleLength let fillEndAngle = 3 * π / 2 + fillAngleLength let fillPath_fill = UIBezierPath(arcCenter: center, radius: radius/2 - arcWidth/2, startAngle: fillStartAngle, endAngle: fillEndAngle, clockwise: true) fillPath_fill.lineWidth = arcWidth fillColor.setStroke() fillPath_fill.stroke() //Drawing container outline on top let outlinePath_outer = UIBezierPath(arcCenter: center, radius: radius / 2 - outlineWidth / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true) let outlinePath_inner = UIBezierPath(arcCenter: center, radius: radius / 2 - arcWidth + outlineWidth / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true) outlinePath_outer.lineWidth = outlineWidth outlinePath_inner.lineWidth = outlineWidth strokeColor.setStroke() outlinePath_outer.stroke() outlinePath_inner.stroke() } } class CircleProgressLayer: CALayer { @NSManaged var progress: CGFloat override class func needsDisplayForKey(key: String) -> Bool { if key == "progress" { return true } return super.needsDisplayForKey(key) } override func actionForKey(key: String) -> CAAction? { if (key == "progress") { if let pres = self.presentationLayer() { let anim: CABasicAnimation = CABasicAnimation.init(keyPath: key) anim.fromValue = pres.progress anim.duration = 0.2 return anim } return super.actionForKey(key) } else { return super.actionForKey(key) } } }
感谢您的帮助!
【问题讨论】:
-
你有没有试过做类似的事情:informit.com/articles/article.aspx?p=1431312&seqNum=5?
-
我相信这就是 actionForKey() -> CAAction 中发生的事情?
标签: ios animation uiview calayer