0

CAKeyframeAnimation を介して表示されている現在のフェイ フレーム画像に関する情報を表示する必要があります。したがって、「値」インデックス 0 の画像が表示されると、その画像に関する情報が NSTextField に表示され、インデックス 1 にアニメーション化されると、その画像に関する情報が表示されます。これを行うことは可能ですか?

CAKeyframeAnimation *theAnimation=[CAKeyframeAnimation animationWithKeyPath:@"contents"];
theAnimation.values = myView.productImages;
theAnimation.duration = 5.0;
theAnimation.repeatCount = HUGE_VALF;
theAnimation.calculationMode = kCAAnimationDiscrete;
theAnimation.fillMode = kCAFillModeRemoved;
[myView.exampleCALayer addAnimation:theAnimation forKey:@"contents"];
[myView.exampleCALayer setNeedsDisplay];
4

2 に答える 2

1

通常、位置などのプロパティは、アニメーションの実行中にタイマーや表示リンクを使用して非常に簡単に観察できますが、監視しようとしているのはコンテンツ プロパティであるため、少し注意が必要です。独自のカスタム プロパティをアニメーション化することをお勧めします。その後、既存のコンテンツ アニメーションと一緒にグループでアニメーション化し、カスタム プロパティが変更されるたびに更新を取得できます。

手順は次のようになります。

  1. CALayer 派生クラスを宣言する
  2. これらのメソッドをオーバーライドします。

    - (id)initWithLayer:(id)layer

    + (BOOL)needsDisplayForKey:(NSString*)key

    - (void)drawInContext:(CGContextRef)ctx

  3. ヘッダーでオーバーライドするプロパティを作成します

  4. プロパティをアニメーション化するキーフレーム アニメーションを作成する

レイヤーの実装は次のようになります。

@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 アプリに適応させることができるはずです。

于 2013-03-14T18:10:09.553 に答える