Я работаю над круговой индикацией выполнения, которую хочу оживить. Все рисует, как ожидалось, и работает, но когда я пытаюсь оживить, я получаю немедленное изменение вместо анимации. Любая помощь будет оценена по достоинству.Неявная анимация на 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, который я скачал из Apple, похоже, что все в порядке.
Вот код рисования:
-(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, которые выполняют некоторые манипуляции с контекстом и путями, которые я не включил, имена функций должны быть достаточно понятными.
Любая помощь была бы принята с благодарностью.
FYI: Я более чем готов сделать эту явную анимацию, если это проще, но я оказался в этом направлении, потому что я тоже не мог сделать эту работу.
Пожалуйста, покажите свой код внутри 'drawLayer: inContext:' –
Добавлен код чертежа, не знаю, почему я его забыл. –