CAKeyframeAnimation具有UIImageView中动画的不同持续时间值

时间:2015-03-16 12:34:31

标签: ios objective-c nsarray core-animation cakeyframeanimation

这里我在CAKeyframeAnimation中显示一些具有固定持续时间1(总帧20,因此1/20 = 0.05f)的帧(.png)。它运行得很好。

- (void)animateImages
{
    self.emoImageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 160, 50, 50)];
    self.emoImageView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:emoImageView];

    NSArray *values = [NSArray arrayWithObjects:
                       (id)[UIImage imageNamed:@"smiley64_1_1.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_2.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_3.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_4.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_5.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_6.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_7.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_8.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_9.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_10.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_11.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_12.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_13.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_14.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_15.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_16.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_17.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_18.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_19.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_20.png"].CGImage, nil];      

    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    //[anim setDuration:[[duration objectAtIndex:i] doubleValue]];
    [anim setDuration:1];
    [anim setValues:values];
    [anim setKeyPath:@"contents"];
    [anim setCalculationMode:@"discrete"];
    [anim setRepeatCount: 90000];
    [self.emoImageView.layer addAnimation:anim forKey:nil];
}

但是现在我想要显示具有不同持续时间的这些帧。我的NSArray有不同的持续时间值:

NSArray *duration = [NSArray arrayWithObjects:
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f], nil];

为此,我对它们使用了for loop,如下所示:

- (void)animateImages
{
    self.emoImageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 160, 50, 50)];
    self.emoImageView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:emoImageView];

    NSArray *values = [NSArray arrayWithObjects:
                       (id)[UIImage imageNamed:@"smiley64_1_1.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_2.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_3.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_4.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_5.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_6.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_7.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_8.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_9.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_10.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_11.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_12.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_13.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_14.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_15.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_16.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_17.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_18.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_19.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_20.png"].CGImage, nil];

    NSArray *duration = [NSArray arrayWithObjects:
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f],
                     [NSNumber numberWithFloat:0.4f], nil];


    for (int i = 0; i < [duration count]; i++)
    {
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
        [anim setDuration:[[duration objectAtIndex:i] doubleValue]];
        [anim setValues:@[[values objectAtIndex:i]]];
        [anim setKeyPath:@"contents"];
        [anim setCalculationMode:@"discrete"];
        [anim setRepeatCount: 90000];
        [self.emoImageView.layer addAnimation:anim forKey:nil];
    }
}

但帧没有显示。如何在CAKeyframeAnimation中为具有不同持续时间的某些帧设置动画?
谢谢您的光临。

2 个答案:

答案 0 :(得分:2)

你做得不对。不要在循环中创建多个关键帧动画。就像创建具有相同持续时间的动画一样,创建单个关键帧动画。但是,要逐帧控制持续时间,请将动画对象上的keyTimes属性设置为您创建的持续时间数组。

请注意,keyTimes的值是动画中每个帧的相对开始时间。它们的范围必须介于0.0到1.0之间,每个后续值必须大于最后一个值:

#define steps 20

NSMutableArray *startTimes = [NSMutableArray arrayWithCapacity: steps];
for (int i = 0; i< steps; i++)
{
  startTimes[i] = @(i* 1.0/2.0);
}

您应该阅读CAKeyframeAnimation上的Xcode文档。他们实际上非常有用。

顺便说一句,每当你的代码一遍又一遍地完成同样的事情时,就值得考虑制作一个循环。就像加载图片一样:

NSMutableArray *images = [NSMutableArray arrayWithCapacity: steps];
for (int i = 0; i< steps; i++)
{
  //The filenames start at 1, so use i+1 to create the filename.
  NSString *filename = [NSString stringWithFormat: @"smiley64_1_%d", i+1];
  images[i] = (id)[UIImage imageNamed: filename].CGImage;
}

另请注意,您通常不应在对imageNamed的调用中包含文件扩展名。如果你不这样做,系统会以适当的分辨率(正常,@ 2x视网膜或@ 3x视网膜)加载图像。我相信包含明确的延伸会破坏这一点,尽管我并不积极。

编辑:

从文档中读取此位:

  

数组中的每个值都是介于0.0和1.0之间的浮点数   定义时间点(指定为分数   动画的总持续时间),在此处应用相应的   关键帧值。数组中的每个连续值必须更大   比以前的值更大或更等。通常,元素的数量   在数组中应该匹配值中的元素数量   属性或path属性中的控制点数。如果他们   不要,你的动画时间可能不是你所期望的。

答案 1 :(得分:0)

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.durationArray = [[NSMutableArray alloc] initWithObjects:
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04",
                             @"0.04", nil];


    [self animateImages];
}

- (void)animateImages
{
    self.emoImageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 160, 50, 50)];
    self.emoImageView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:emoImageView];


    NSArray *values = [NSArray arrayWithObjects:
                       (id)[UIImage imageNamed:@"smiley64_1_1.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_2.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_3.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_4.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_5.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_6.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_7.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_8.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_9.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_10.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_11.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_12.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_13.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_14.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_15.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_16.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_17.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_18.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_19.png"].CGImage,
                       (id)[UIImage imageNamed:@"smiley64_1_20.png"].CGImage, nil];


    // The total duration of my animation
    float Duration = 0;
    for (int i = 0; i < [durationArray count]; i++)
    {
        Duration = Duration + [[durationArray objectAtIndex: i] floatValue];
    }

    NSMutableArray *keyTimes = [[NSMutableArray alloc] init];
    float keyTimesRow = 0.0;
    for (int i = 0; i < [durationArray count]; i++)
    {
        keyTimesRow = keyTimesRow + ([[durationArray objectAtIndex: i] floatValue]/Duration);
        NSNumber *k = [NSNumber numberWithFloat:keyTimesRow];
        //keyTimes[0] = @(0.0);
        [keyTimes addObject:k];
    }


    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    [anim setDuration:Duration];
    [anim setKeyTimes:keyTimes];
    [anim setValues:values];
    [anim setKeyPath:@"contents"];
    [anim setRepeatCount: -1];
    [self.emoImageView.layer addAnimation:anim forKey:nil];
}

这里我只计算动画的总持续时间。所以后者我可以用我的动画实例设置它。

// The total duration of my animation
        float Duration = 0;
        for (int i = 0; i < [durationArray count]; i++)
        {
            Duration = Duration + [[durationArray objectAtIndex: i] floatValue];
        }

这里我从每帧的时间间隔创建KeyTimes数组。并创建keyTimes数组。

NSMutableArray *keyTimes = [[NSMutableArray alloc] init];
        float keyTimesRow = 0.0;
        for (int i = 0; i < [durationArray count]; i++)
        {
            keyTimesRow = keyTimesRow + ([[durationArray objectAtIndex: i] floatValue]/Duration);
            NSNumber *k = [NSNumber numberWithFloat:keyTimesRow];
            //keyTimes[0] = @(0.0);
            [keyTimes addObject:k];
        }

最后在动画实例中设置所有这些。

CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
        [anim setDuration:Duration];
        [anim setKeyTimes:keyTimes];
        [anim setValues:values];
        [anim setKeyPath:@"contents"];
        [anim setRepeatCount: -1];
        [self.emoImageView.layer addAnimation:anim forKey:nil];