0

我需要显示有关通过 CAKeyframeAnimation 显示的当前 fey 帧图像的信息。因此,当显示“值”索引 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: 方法中,您可以监控计数器值,然后做出相应的响应。

不过,这可能有点棘手,因为您要同时为两个属性设置动画。您必须使用一个组才能使其正常工作:

- (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 编写的,但您应该能够在 OSX 应用程序中调整 Core Animation 特定代码。

于 2013-03-14T18:10:09.553 回答
0

哇,这是一个伟大的工作!!!我会用的……</p>

请注意,我在 Xcode 5 上,我注意到只有第一个动画“slideShowAnimation”被触发。

我可以通过添加这两行来解决它:

[slideShowAnimation setBeginTime:0];
[counterAnimation setBeginTime:0];

感谢分享。- 网卡

于 2014-02-07T16:27:44.690 回答