Обычно вы можете наблюдать свойство, как положение, например, довольно легко с помощью таймера или ссылку дисплея в то время как анимация работает, однако, так как это свойство содержимого вы пытаетесь контролировать, все мало более сложным. Я бы предположил, что вы анимируете свое собственное обычное свойство. Затем вы можете анимировать его в группе вместе с существующей анимацией содержимого и получать обновления всякий раз, когда изменяется ваше настраиваемое свойство.
шаги идти что-то вроде этого:
- Объявите CALayer производного класса
Override эти методы:
- (id)initWithLayer:(id)layer
+ (BOOL)needsDisplayForKey:(NSString*)key
- (void)drawInContext:(CGContextRef)ctx
Создать свойство, которое вы хотите переопределить в заголовке
- Создание ключевых кадров анимации, которая оживляет вашу собственность
Вот что ваш слой может выглядеть в его реализации:
@implementation MLImageLayer
- (id)initWithLayer:(id)layer
{
if(self = [super initWithLayer:layer]) {
if([layer isKindOfClass:[MLImageLayer class]]) {
MLImageLayer *other = (MLImageLayer*)layer;
[self setCounter:[other counter]];
}
}
return self;
}
+ (BOOL)needsDisplayForKey:(NSString*)key
{
if ([key isEqualToString:@"counter"]) {
return YES;
} else {
return [super needsDisplayForKey:key];
}
}
- (void)drawInContext:(CGContextRef)ctx
{
DLog(@"Counter is: %d", _counter);
}
@end
Затем, чтобы фактически охарактеризовать недвижимость, выполните следующие действия:
CAKeyframeAnimation *counterAnimation = [CAKeyframeAnimation
animationWithKeyPath:@"counter"];
[counterAnimation setDelegate:self];
NSArray *values = @[@(0), @(1), @(2), @(3), @(4), @(5)];
[counterAnimation setValues:values];
[counterAnimation setDuration:5.0];
[counterAnimation setRepeatCount:HUGE_VALF];
[counterAnimation setCalculationMode:kCAAnimationDiscrete];
Теперь, в методе -drawInContext вашего производного уровня, вы можете отслеживать значение счетчика и затем отвечать соответствующим образом.
Это может быть немного сложнее, поскольку вы одновременно анимации двух свойств. Вы должны будете использовать группу, чтобы заставить его работать правильно:
- (void)viewDidLoad
{
[super viewDidLoad];
_animationLayer = [MLImageLayer layer];
[_animationLayer setBounds:CGRectMake(0.0f, 0.0f, 400.0f, 320.0f)];
[_animationLayer setPosition:[[self view] center]];
UIImage *image = [UIImage imageNamed:@"Countryside.jpg"];
[_animationLayer setContents:(__bridge id)[image CGImage]];
[[[self view] layer] addSublayer:_animationLayer];
CAKeyframeAnimation *slideShowAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
[slideShowAnimation setValues:@[(id)[[UIImage imageNamed:@"Countryside.jpg"] CGImage],
(id)[[UIImage imageNamed:@"Countryside-1.jpg"] CGImage],
(id)[[UIImage imageNamed:@"Countryside-2.jpg"] CGImage],
(id)[[UIImage imageNamed:@"Countryside-3.jpg"] CGImage],
(id)[[UIImage imageNamed:@"Countryside-4.jpg"] CGImage],
(id)[[UIImage imageNamed:@"Countryside-5.jpg"] CGImage]]];
[slideShowAnimation setDuration:5.0];
[slideShowAnimation setDelegate:self];
[slideShowAnimation setRepeatCount:HUGE_VALF];
[slideShowAnimation setCalculationMode:kCAAnimationDiscrete];
CAKeyframeAnimation *counterAnimation = [CAKeyframeAnimation animationWithKeyPath:@"counter"];
[counterAnimation setDelegate:self];
NSArray *values = @[@(0), @(1), @(2), @(3), @(4), @(5)];
[counterAnimation setValues:values];
[counterAnimation setDuration:5.0];
[counterAnimation setRepeatCount:HUGE_VALF];
[counterAnimation setCalculationMode:kCAAnimationDiscrete];
CAAnimationGroup *group = [CAAnimationGroup animation];
[group setDuration:5.0];
[group setRepeatCount:HUGE_VALF];
[group setAnimations:@[slideShowAnimation, counterAnimation]];
[_animationLayer addAnimation:group forKey:nil];
}
Я отправил проект up on github. Он написан для iOS, но вы должны иметь возможность адаптировать специальный код Core Animation в приложении OSX.
Спасибо за отличный ответ! Мне нужно протестировать его на OS X, но когда я попробовал ретрансляцию github с помощью симулятора iOS 6.1, он будет регистрировать одинаковое значение счетчика примерно 20 раз для каждого слайда.Вы заметили это? – dbainbridge
Да. Ваш drawInContext вызывается на частоте кадров слоя. Вам нужно будет следить за * изменениями * в значение счетчика. –