У меня есть подкласс CALayer, MyLayer, который имеет свойство NSInteger, называемое myInt. Я бы очень хотел оживить это свойство через CABasicAnimation, но, похоже, CABasicAnimation работает только с так называемыми "анимативными" свойствами (границами, позицией и т.д.). Есть ли что-то, что я могу переопределить, чтобы сделать мое пользовательское свойство myInt анимированным?
Анимация пользовательского свойства подкласса CALayer
Ответ 1
Да, это возможно (только в последних версиях Core Animation, хотя, я считаю, то есть iPhone 3.0+ и OS X 10.6 +).
-
Сделайте вашу динамическую структуру так, чтобы CA реализовал для вас аксессоры:
@dynamic myInt;
-
Сообщите слою, что изменения свойства требуют перерисовки:
+ (BOOL)needsDisplayForKey:(NSString*)key { if ([key isEqualToString:@"myInt"]) { return YES; } else { return [super needsDisplayForKey:key]; } }
-
Используйте значение
myInt
в вашем методеdrawInContext:
. Теперь, когда вы анималируетеmyInt
, Core Animation будет интерполировать значения для каждого шага анимации и повторно просить слой рисовать сам. -
Если вы также хотите включить неявные анимации для этого свойства, также переопределите
actionForKey:
.
Ответ 2
Существует способ сохранить iVars ваших пользовательских подклассов CALayer. Вы переопределяете initWithLayer:, метод, который вызывается для создания копии пользовательских слоев. Например, если у вас есть слой, в котором вы хотите создать настраиваемое свойство под названием "угол", вы можете использовать следующий код:
@implementation AngledLayer
@synthesize angle = _angle
// Tell Core Animation that this key should be animated
+ (BOOL) needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:@"angle"]) return YES;
return [super needsDisplayForKey:key];
}
// Make sure that, when the layer is copied, so is the custom ivar
- (id) initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self) {
AngledLayer *angledVersion = (AngledLayer *)layer;
self.angle = angledVersion.angle;
}
return self;
}
И помоги своему дяде! Обратите внимание: вы не можете использовать этот объект с неявной анимацией, для которой вам также нужно будет переопределить метод actionForKey:.