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

标签 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 循环,如下所示:

- (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 中为一些具有不同持续时间的帧设置动画?
感谢您的光临。

最佳答案

你做的不对。不要在循环中创建多个关键帧动画。就像创建具有相同持续时间的动画一样,创建单个关键帧动画。但是,要逐帧控制持续时间,请将动画对象的 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 视网膜)加载图像。我相信包括一个明确的扩展会破坏它,尽管我不是肯定的。

编辑:

从文档中阅读这一点:

Each value in the array is a floating point number between 0.0 and 1.0 that defines the time point (specified as a fraction of the animation’s total duration) at which to apply the corresponding keyframe value. Each successive value in the array must be greater than, or equal to, the previous value. Usually, the number of elements in the array should match the number of elements in the values property or the number of control points in the path property. If they do not, the timing of your animation might not be what you expect.

关于ios - CAKeyframeAnimation 在 UIImageView 中具有不同的动画持续时间值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29076942/

相关文章:

ios - ScrollView 中的分页和重用 View

ios - iOS 中的交互式视频 : Is it possible to trigger specific actions in code by tapping discrete parts in the video?

objective-c - 在 Objective C 中从 NSDictionary 对象创建 URL 查询参数

iphone - 推式转场场景有效,模态转场场景不行?

iphone - ios - 如何用名称初始化数组?

ios - 如何在 Swift 中为 SequenceOf 创建扩展?

ios - 如何在快速点击按钮时从第二个 View Controller 调用第一个 View Controller 功能?

iphone - 自定义 uitablviewcell 不在 Controller 中调用 didSelectRowAtIndexPath

ios - 从字典中提取值的神奇方法

objective-c - 在 NSMutableArray 中观察计数