这里是我的CircleView类:
import UIKit class CircleView: UIView { override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.clearColor() } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func drawRect(rect: CGRect) { // Get the Graphics Context var context = UIGraphicsGetCurrentContext(); // Set the circle outerline-width CGContextSetLineWidth(context,5.0); // Set the circle outerline-colour UIColor.redColor().set() // Create Circle CGContextAddArc(context,(frame.size.width)/2,frame.size.height/2,(frame.size.width - 10)/2,0.0,CGFloat(M_PI * 2.0),1) // Draw CGContextStrokePath(context); } }
下面是我如何将它添加到我的视图控制器中的视图层次结构:
func addCircleView() { let diceRoll = CGFloat(Int(arc4random_uniform(7))*50) var circleWidth = CGFloat(200) var circleHeight = circleWidth // Create a new CircleView var circleView = CircleView(frame: CGRectMake(diceRoll,circleWidth,circleHeight)) view.addSubview(circleView) }
有没有办法动画绘制的圆圈超过1秒?
示例,部分通过动画它将看起来像这个图像中的蓝线:
CAShapeLayer
.然后,我们可以使用
CABasicAnimation
动画CAShapeLayer的
strokeEnd
属性从0.0到1.0。 strokeEnd是这里魔法的一大部分;从文档:
Combined with the strokeStart property,this property defines the
subregion of the path to stroke. The value in this property indicates
the relative point along the path at which to finish stroking while
the strokeStart property defines the starting point. A value of 0.0
represents the beginning of the path while a value of 1.0 represents
the end of the path. Values in between are interpreted linearly along
the path length.
如果我们将strokeEnd设置为0.0,它不会绘制任何东西。如果我们将它设置为1.0,它将绘制一个完整的圆。如果我们将它设置为0.5,它将绘制一个半圈。等等
所以,开始,让我们在你的CircleView的init函数中创建一个CAShapeLayer,并将该图层添加到视图的子图层中(也要确保删除drawRect函数,因为图层现在将绘制圆):
let circleLayer: CAShapeLayer! override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.clearColor() // Use UIBezierPath as an easy way to create the CGPath for the layer. // The path should be the entire circle. let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0,y: frame.size.height / 2.0),radius: (frame.size.width - 10)/2,startAngle: 0.0,endAngle: CGFloat(M_PI * 2.0),clockwise: true) // Setup the CAShapeLayer with the path,colors,and line width circleLayer = CAShapeLayer() circleLayer.path = circlePath.CGPath circleLayer.fillColor = UIColor.clearColor().CGColor circleLayer.strokeColor = UIColor.redColor().CGColor circleLayer.lineWidth = 5.0; // Don't draw the circle initially circleLayer.strokeEnd = 0.0 // Add the circleLayer to the view's layer's sublayers layer.addSublayer(circleLayer) }
注意:我们正在设置circleLayer.strokeEnd = 0.0,以便不立即绘制圆形。
func animateCircle(duration: NSTimeInterval) { // We want to animate the strokeEnd property of the circleLayer let animation = CABasicAnimation(keyPath: "strokeEnd") // Set the animation duration appropriately animation.duration = duration // Animate from 0 (no circle) to 1 (full circle) animation.fromValue = 0 animation.toValue = 1 // Do a linear animation (i.e. the speed of the animation stays the same) animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) // Set the circleLayer's strokeEnd property to 1.0 now so that it's the // right value when the animation ends. circleLayer.strokeEnd = 1.0 // Do the actual animation circleLayer.addAnimation(animation,forKey: "animateCircle") }
然后,我们需要做的是更改addCircleView函数,以便在将CircleView添加到其superview时触发动画:
func addCircleView() { let diceRoll = CGFloat(Int(arc4random_uniform(7))*50) var circleWidth = CGFloat(200) var circleHeight = circleWidth // Create a new CircleView var circleView = CircleView(frame: CGRectMake(diceRoll,circleHeight)) view.addSubview(circleView) // Animate the drawing of the circle over the course of 1 second circleView.animateCircle(1.0) }
所有放在一起应该看起来像这样:
注意:它不会像这样重复,它会保持一个完整的圆后它的动画。