画圆的动画 [英] Animate drawing of a circle
问题描述
我正在寻找一种动画制作圆形图的方法。我已经能够创建圆,但是将其全部绘制。
I'm looking for a way to animate the drawing of a circle. I have been able to create the circle, but it draws it all together.
这是我的 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);
}
}
这是将其添加到视图层次结构中的方法在我的视图控制器中:
And here is how I add it to the view hierarchy in my view controller:
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, 0, circleWidth, circleHeight))
view.addSubview(circleView)
}
是否有办法在1秒内对圆的绘制进行动画处理?
Is there a way to animate the drawing of the circle over 1 second?
例如,在动画过程的一部分,它看起来像这张图中的蓝线:
Example, part way through the animation it would look something like the blue line in this image:
< img src = https://i.stack.imgur.com/FP4Hum.png alt =局部动画>
推荐答案
最简单的方法是利用核心动画的力量为您完成大部分工作。为此,我们必须将您的圆图绘制代码从您的 drawRect
函数移动到 CAShapeLayer
。然后,我们可以使用 CABasicAnimation
为 CAShapeLayer
的 strokeEnd
属性来自 0.0
到 1.0
。 strokeEnd
是这里魔术的重要组成部分;来自文档:
The easiest way to do this is to use the power of core animation to do most of the work for you. To do that, we'll have to move your circle drawing code from your drawRect
function to a CAShapeLayer
. Then, we can use a CABasicAnimation
to animate CAShapeLayer
's strokeEnd
property from 0.0
to 1.0
. strokeEnd
is a big part of the magic here; from the docs:
与strokeStart属性结合使用,该属性定义了描边路径的
子区域。此属性中的值指示
沿行程的相对点,在该路径上完成笔划,而
strokeStart属性定义起点。值0.0
表示路径的开始,而值1.0表示
路径的结束。中间的值沿路径长度
线性解释。
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
,它将画一个半圆。等等。
If we set strokeEnd
to 0.0
, it won't draw anything. If we set it to 1.0
, it'll draw a full circle. If we set it to 0.5
, it'll draw a half circle. etc.
因此,首先在 CircleView中创建
CAShapeLayer
code>的 init
函数并将该层添加到视图的子层
中(也请确保删除 drawRect
函数,因为该图层现在将绘制圆):
So, to start, lets create a CAShapeLayer
in your CircleView
's init
function and add that layer to the view's sublayers
(also be sure to remove the drawRect
function since the layer will be drawing the circle now):
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(Double.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
设置为不会立即绘制圆圈。
Note: We're setting circleLayer.strokeEnd = 0.0
so that the circle isn't drawn right away.
现在,让我们添加一个可以调用以触发圆形动画的函数:
Now, lets add a function that we can call to trigger the circle animation:
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: CAMediaTimingFunctionName.linear)
// 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
时,它会触发动画:
Then, all we need to do is change your addCircleView
function so that it triggers the animation when you add the CircleView
to its 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, 0, circleWidth, circleHeight))
view.addSubview(circleView)
// Animate the drawing of the circle over the course of 1 second
circleView.animateCircle(1.0)
}
所有内容应如下所示:
注意:它不会像这样重复,它会在动画后保持完整的圆圈。
Note: It won't repeat like that, it'll stay a full circle after it animates.
这篇关于画圆的动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!