通常可以观察到类似位置的特性,例如,很容易使用定时器或显示器连接,而在动态画面的运行,但是,因为它是你想监控的内容属性,事情不大更棘手。我建议你动画你自己的自定义属性。然后,您可以将其与现有内容动画一起在组中制作动画,并在您的自定义属性更改时获取更新。
的步骤去是这样的:
- 声明一个CALayer的派生类
重写这些方法:
- (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编写的,但您应该可以在OSX应用程序中调整Core Animation特定的代码。
感谢您的真棒回答!我需要在OS X上测试它,但是当我使用iOS 6.1模拟器尝试github repo时,它会为每张幻灯片记录约20次相同的计数器值。你注意到了吗? – dbainbridge 2013-03-15 14:31:42
是的。 drawInContext正在以图层的帧速率调用。你必须观察*计数器值的变化*。 – 2013-03-15 16:06:51