通常、位置などのプロパティは、アニメーションの実行中にタイマーや表示リンクを使用して非常に簡単に観察できますが、監視しようとしているのはコンテンツ プロパティであるため、少し注意が必要です。独自のカスタム プロパティをアニメーション化することをお勧めします。その後、既存のコンテンツ アニメーションと一緒にグループでアニメーション化し、カスタム プロパティが変更されるたびに更新を取得できます。
手順は次のようになります。
- 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: メソッドに戻り、カウンター値を監視して、それに応じて応答できます。
ただし、2 つのプロパティを同時にアニメーション化するため、これは少し難しい場合があります。正しく機能させるには、グループを使用する必要があります。
- (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];
}
プロジェクトを githubに投稿しました。これは iOS 向けに書かれていますが、Core Animation 固有のコードを OSX アプリに適応させることができるはずです。