我想创建一个动画。我可以解释这个问题的最佳方法是,如果你能想象画一个圆圈。它从顶部或12点钟开始,顺时针顺时针绘制,直到它在10秒左右的空间内成为一个完整的圆圈。
我所遇到的壁橱是使用Core Animation(使用示例代码here)绘制围绕中心点旋转的点。但我对如何绘制圆圈感到茫然?任何建议都非常受欢迎。
非常感谢:)
答案 0 :(得分:161)
你真正应该做的是动画CAShapeLayer的笔划,其中路径是一个圆圈。这将使用Core Animation加速,并且在-drawRect中绘制圆的一部分时不那么混乱:。
下面的代码将在屏幕中央创建一个圆形图层,并顺时针为其设置动画,使其看起来好像正在绘制。你当然可以使用你想要的任何形状。 (您可以阅读Ole Begemanns博客上的this article以了解有关如何为形状图层的笔触设置动画的更多信息。)
注意: stoke属性与图层上的边框属性不同。要更改笔划的宽度,您应该使用“lineWidth”而不是“borderWitdh”等。
// Set up the shape of the circle
int radius = 100;
CAShapeLayer *circle = [CAShapeLayer layer];
// Make a circular shape
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius)
cornerRadius:radius].CGPath;
// Center the shape in self.view
circle.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
CGRectGetMidY(self.view.frame)-radius);
// Configure the apperence of the circle
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 5;
// Add to parent layer
[self.view.layer addSublayer:circle];
// Configure animation
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration = 10.0; // "animate over 10 seconds or so.."
drawAnimation.repeatCount = 1.0; // Animate only once..
// Animate from no part of the stroke being drawn to the entire stroke being drawn
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue = [NSNumber numberWithFloat:1.0f];
// Experiment with timing to get the appearence to look the way you want
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
// Add the animation to the circle
[circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"];
答案 1 :(得分:8)
根据@David的回答,这是问题的另一种解决方案。这种方法可让您设置圆圈动画的方向,并提供更多控制。 修改:我已在how to draw a circle with Swift上撰写了一篇博客文章,我将尽力与博彩公司保持联系。检查下面的代码是否适合您。
let radius = 100.0
// Create the circle layer
var circle = CAShapeLayer()
// Set the center of the circle to be the center of the view
let center = CGPointMake(CGRectGetMidX(self.frame) - radius, CGRectGetMidY(self.frame) - radius)
let fractionOfCircle = 3.0 / 4.0
let twoPi = 2.0 * Double(M_PI)
// The starting angle is given by the fraction of the circle that the point is at, divided by 2 * Pi and less
// We subtract M_PI_2 to rotate the circle 90 degrees to make it more intuitive (i.e. like a clock face with zero at the top, 1/4 at RHS, 1/2 at bottom, etc.)
let startAngle = Double(fractionOfCircle) / Double(twoPi) - Double(M_PI_2)
let endAngle = 0.0 - Double(M_PI_2)
let clockwise: Bool = true
// `clockwise` tells the circle whether to animate in a clockwise or anti clockwise direction
circle.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: clockwise).CGPath
// Configure the circle
circle.fillColor = UIColor.blackColor().CGColor
circle.strokeColor = UIColor.redColor().CGColor
circle.lineWidth = 5
// When it gets to the end of its animation, leave it at 0% stroke filled
circle.strokeEnd = 0.0
// Add the circle to the parent layer
self.layer.addSublayer(circle)
// Configure the animation
var drawAnimation = CABasicAnimation(keyPath: "strokeEnd")
drawAnimation.repeatCount = 1.0
// Animate from the full stroke being drawn to none of the stroke being drawn
drawAnimation.fromValue = NSNumber(double: fractionOfCircle)
drawAnimation.toValue = NSNumber(float: 0.0)
drawAnimation.duration = 30.0
drawAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
// Add the animation to the circle
circle.addAnimation(drawAnimation, forKey: "drawCircleAnimation")
答案 2 :(得分:3)
我得到了这个问题的解决方案,代码如下。我似乎已经搞砸了我对手头问题的解释,所以把它改写成另一个问题,用正确的解决方案回答,见here
感谢大家的建议!
-(void)drawRect:(CGRect)rect
{
// Drawing code
CGRect allRect = self.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();
// Draw background
CGContextSetRGBStrokeColor(context, self.strokeValueRed, self.strokeValueGreen, self.strokeValueBlue, self.strokeValueAlpha); // white
CGContextSetLineWidth(context, 5);
// Draw progress
CGPoint center = CGPointMake(allRect.size.width / 2, allRect.size.height / 2);
CGFloat radius = (allRect.size.width - 4) / 2;
CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
CGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
CGContextStrokePath(context);
}
答案 3 :(得分:0)
好的我有部分修复。我发现以下代码绘制了一个圆圈段。它基本上是一个UIView子类,每次更新其进度时都会触发drawRect。我现在唯一的问题是如何更改它,以便不是绘制剖面或切片而只绘制圆形笔划?
-(void)drawRect:(CGRect)rect
{
// Drawing code
CGRect allRect = self.bounds;
CGRect circleRect = CGRectInset(allRect, 2.0f, 2.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
// Draw background
CGContextSetRGBStrokeColor(context, self.strokeValueRed, self.strokeValueGreen, self.strokeValueBlue, self.strokeValueAlpha); // white
CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 0.1f); // translucent white
CGContextSetLineWidth(context, self.lineWidth);
CGContextFillEllipseInRect(context, circleRect);
CGContextStrokeEllipseInRect(context, circleRect);
// Draw progress
CGPoint center = CGPointMake(allRect.size.width / 2, allRect.size.height / 2);
CGFloat radius = (allRect.size.width - 4) / 2;
CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
CGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // white
CGContextMoveToPoint(context, center.x, center.y);
CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
CGContextClosePath(context);
CGContextFillPath(context);
}