Почему анимация пользовательских свойств CALayer приводит к тому, что другие свойства не равны нулю во время анимации?
У меня есть пользовательский CALayer (скажем, CircleLayer), содержащий пользовательские свойства (радиус и оттенок). Этот слой отображается в методе drawInContext:.
- (void)drawInContext:(CGContextRef)ctx {
NSLog(@"Drawing layer, tint is %@, radius is %@", self.tint, self.radius);
CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);
CGContextMoveToPoint(ctx, centerPoint.x, centerPoint.y);
CGContextAddArc(ctx, centerPoint.x, centerPoint.y, [self.radius doubleValue], radians(0), radians(360), 0);
CGContextClosePath(ctx);
/* Filling it */
CGContextSetFillColorWithColor(ctx, self.tint.CGColor);
CGContextFillPath(ctx);
}
Я хочу, чтобы радиус был анимированным, поэтому я реализовал
+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([key isEqualToString:@"radius"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
И анимация выполняется следующим образом:
CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"radius"];
theAnimation.duration=2.0;
theAnimation.fromValue=[NSNumber numberWithDouble:100.0];
theAnimation.toValue=[NSNumber numberWithDouble:50.0];
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[circleLayer addAnimation:theAnimation forKey:@"animateRadius"];
circleLayer.radius = [NSNumber numberWithDouble:50.0];
drawInContext: вызывается как ожидалось во время анимации, чтобы перерисовать круг, однако оттенок устанавливается на нуль, как только начинается анимация, и возвращается к исходному значению, когда анимация заканчивается.
Я пришел к выводу, что если я хочу анимировать настраиваемое свойство и хочу, чтобы другие свойства сохраняли свою ценность во время анимации, мне тоже нужно их оживить, что я считаю не удобным вообще.
Цель состоит не в том, чтобы вырастить/сжать круг, я знаю, что могу использовать трансформацию для этого. Это просто проиллюстрировать простым примером проблему анимации единого пользовательского свойства без необходимости анимировать все остальные.
Я сделал простой проект, иллюстрирующий проблему, которую вы можете найти здесь:
Пример проекта, иллюстрирующий проблему
Вероятно, я не понял, как работает CoreAnimation, я провел интенсивный поиск, но я не зацикливаюсь. Кто-нибудь знает?
Ответы
Ответ 1
Если я правильно понял ваш вопрос, все будет так. Когда вы добавляете анимацию в CALayer, она создает так называемую копию презентации этого слоя, используя initWithLayer:
. Уровень презентации содержит фактическое анимированное состояние для каждого кадра анимации, тогда как исходный уровень имеет конечное состояние. Проблема с анимацией ваших собственных свойств заключается в том, что CALayer не копирует их все в initWithLayer:
. Если это ваш случай, вы должны переопределить initWithLayer:
и настроить все свойства, необходимые для анимации, то есть как оттенок, так и радиус.
Ответ 2
+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([key isEqualToString:@"radius"] || [key isEqualToString:@"tint"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
Анимация может потребовать, чтобы все свойства контекста отвечали на обновление.