我正在研究一个我想要动画的圆形进度条。一切都按预期绘制并运行,但是当我尝试动画时,我会立即改变而不是动画。任何帮助,将不胜感激。CALayer上的隐式动画不是动画
这里是我的层:
@interface CircularProgressLayer : CALayer
@property (nonatomic, assign) CGFloat progressDegrees;
@property (nonatomic, assign) CGFloat trackWidth;
@end
@implementation CircularProgressLayer : CALayer
@dynamic progressDegrees;
@dynamic trackWidth;
- (id)initWithLayer:(id)layer
{
if ((self = [super initWithLayer:layer]))
{
if ([layer isKindOfClass:[CircularProgressLayer class]])
{
self.progressDegrees = ((CircularProgressLayer*)layer).progressDegrees;
}
}
return self;
}
// Instruct to Core Animation that a change in the custom property should automatically trigger a redraw of the layer.
+ (BOOL)needsDisplayForKey:(NSString*)key
{
if ([key isEqualToString:@"progressDegrees"])
{
return YES;
}
if ([key isEqualToString:@"trackWidth"])
{
return YES;
}
return [super needsDisplayForKey:key];
}
// Needed to support implicit animation of this property.
// Return the basic animation the implicit animation will leverage.
- (id<CAAction>)actionForKey:(NSString *)key
{
if ([key isEqualToString:@"progressDegrees"])
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:key];
animation.fromValue = [[self presentationLayer] valueForKey:key];
animation.duration = 5.0;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
return animation;
}
return [super actionForKey:key];
}
据我了解,在actionForKey:
返回动画应该是所有需要做的动画作品,但我什么也没得到。我的所有绘图目前都包含在我的视图的drawLayer:inContext:
方法中,该方法实现了此图层(因为它在我学会了必须将其放置到一个图层中以使其生成动画之前就已经创建为drawRect代码,并且我还没有将所有内容),但我从苹果下载的sample code使它看起来像这就好了。
这里是绘图代码:
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
UIGraphicsPushContext(context);
[self drawTrackInContext:context];
[self drawProgressInContext:context];
UIGraphicsPopContext();
}
- (void)drawProgressInContext:(CGContextRef)context
{
if (self.progress < 1)
{
// No progress, get out
return;
}
CGSize size = self.bounds.size;
FlipContextVertically(size);
CGContextSaveGState(context);
{
UIBezierPath *circle = [self circle];
CGContextSetLineWidth(context, 0.0);
CGFloat degrees = 360.0;
for (int i = 0; i < degrees; i++)
{
if (i > ((RMONCircularProgressLayer *)self.layer).progressDegrees)
{
break;
}
CGFloat theta = 2 * M_PI * (CGFloat) i/degrees;
CGFloat x = self.radius * sin(theta);
CGFloat y = self.radius * cos(theta);
MovePathCenterToPoint(circle, CGPointMake(x, y));
OffsetPath(circle, CGSizeMake(size.width/2, size.height/2));
CGContextSetFillColorWithColor(context, [self colorForDegree:i].CGColor);
CGContextAddPath(context, circle.CGPath);
CGContextDrawPath(context, kCGPathFillStroke);
}
}
CGContextRestoreGState(context);
}
- (void)drawTrackInContext:(CGContextRef)context
{
CGContextSaveGState(context);
{
// Draw the circle covering middle of the screen
CGSize size = self.bounds.size;
CGContextSetLineWidth(context, self.trackWidth); // will only be filled color
CGContextSetStrokeColorWithColor(context, self.trackColor.CGColor);
CGContextSetFillColorWithColor(context, self.fillColor.CGColor);
CGContextSetAlpha(context, 1.0);
CGContextAddArc(context, (CGFloat)size.width/2.0, (CGFloat)size.height/2.0, self.radius, 0, (CGFloat)M_PI*2.0, 1);
CGContextDrawPath(context, kCGPathFillStroke);
}
CGContextRestoreGState(context);
}
drawTrackInContext
只是画一个圆圈,在圆的进展将被包含。 是我期望生成动画的绘图代码。有一些来自iOS Drawing的助手函数Erica Sadun做了一些我没有包括的上下文和路径操作,函数名应该是相当自我解释的。
任何帮助将不胜感激。
仅供参考:如果这更容易,我更愿意将其作为一个明确的动画,但是我最终走向了这个方向,因为我也无法做到这一点。
请在'drawLayer:inContext:' –
内显示您的代码添加了绘图代码,不知道为什么我忘了它。 –