2

标题可能不太清楚,但我想做的是让 UIImageView 显示一系列图像(有点像 gif),我通过将 设置animationImages为图像数组然后调用[imageView startAnimating];. 这工作正常。我还有用 CABasicAnimation 移动 UIImageView 的代码,这个动画代码也可以正常工作。但是,当我尝试同时为 UIImageView 的图像设置动画并尝试移动 UIImageView 时,UIImageView 的图像停止动画。有解决方法吗?

这是我为 UIImageView 的内容设置动画的代码:

    self.playerSprite = [[UIImageView alloc] initWithImage:[self.player.animationImages objectAtIndex:0]];
    [self.playerSprite setFrame:CGRectMake(self.center.x, self.center.y, self.tileSet.constants.TILE_WIDTH, self.tileSet.constants.TILE_HEIGHT)];
    self.playerSprite.animationImages = self.player.animationImages;
    self.playerSprite.animationDuration = self.tileSet.constants.animationDuration;
    self.playerSprite.animationRepeatCount = 0; //Makes it repeat indefinitely

这是我使用 CABasicAnimation 为 UIImageView 设置动画的代码:

float playerSpriteX = self.playerSprite.center.x;
float playerSpriteY = self.playerSprite.center.y;

CABasicAnimation *moveAnimation = [CABasicAnimation animation];
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(playerSpriteX + TILE_WIDTH, playerSpriteY)];
[moveAnimation setDelegate:self];
[moveAnimation setFillMode:kCAFillModeForwards];
[moveAnimation setRemovedOnCompletion:NO];
[moveAnimation setDuration:MOVE_ANIMATION_DURATION];       
[self.playerSprite.layer addAnimation:moveAnimation forKey:@"position"];

因此,当 UIImageView 的位置被动画化时,gif 效果不起作用。我的问题是如何做到这一点,以便 UIImageView 在其位置被动画化时循环遍历一组图像?

4

4 回答 4

6

这是猜测,我根本没有测试过这个想法,但是您是否考虑过以与动画位置相同的方式实现图像动画,使用CAKeyframeAnimation? 您需要CGImage从您的数组构造一个对象UIImage数组(以设置values关键帧动画的属性),但它看起来像一个非常简单的转换:

CAKeyframeAnimation *imageAnimation = [CAKeyframeAnimation animation];
imageAnimation.calculationMode = kCAAnimationDiscrete; // or maybe kCAAnimationPaced
imageAnimation.duration = self.tileSet.constants.animationDuration;
imageAnimation.repeatCount = HUGE_VALF;
// the following method will need to be implemented to cast your UIImage array to CGImages
imageAnimation.values = [self animationCGImagesArray];
[self.playerSprite.layer addAnimation:imageAnimation forKey:@"contents"];

-(NSArray*)animationCGImagesArray {
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:[self.player.animationImages count]];
    for (UIImage *image in self.player.animationImages) {
        [array addObject:(id)[image CGImage]];
    }
    return [NSArray arrayWithArray:array];
}
于 2013-04-19T23:18:07.750 回答
1

您的“基本”问题从这一行开始:

CABasicAnimation *moveAnimation = [CABasicAnimation animation];

一个CABasicAnimation对象只使用一个关键帧。这意味着您正在制作动画的图层的内容只绘制一次,然后在动画期间使用该图像。

Seamus 建议使用 aCAKeyframeAnimation是解决该问题的一种方法——关键帧动画将多次重绘动画层的内容,因此为每个关键帧绘制连续图像将为内容和位置设置动画。

于 2013-04-20T04:39:24.030 回答
1

我刚刚做了类似的事情。我使用的代码如下所示:

    CGRect r = ziv.frame;
    r.origin.x += WrongDistance;
    [ziv startAnimating];
    [UIView animateWithDuration:3.0 animations:^(void){
        [ziv setFrame:r];
    } completion:^(BOOL finished){

        [ziv stopAnimating];

        if (finished){
            // not canceled in flight
            if (NumWrong == MaxWrong)
                [self endOfGame:NO];
            else
                [self nextRound:self];
        }
    }];

也许您遇到的问题是因为两个动画都在同一个线程上?

于 2013-04-15T23:15:59.723 回答
1

这不是制作精灵的好方法。我可以坚持认为您应该使用 OpenGL,但可能没有必要走那么远;你可以用一个层的核心动画来完成这一切,我认为你这样做比尝试使用成熟的 UIImageView 更好。

使用一个图层的核心动画,我可以让这个吃豆人精灵在他的嘴巴张开和合拢的同时在屏幕上显示动画;这不就是你的想法吗?

在此处输入图像描述

这是一个显示动画的视频!

http://www.youtube.com/watch?v=WXCLc9ww8MI

然而创建动画的实际代码非常简单:只有两层动画(核心动画),一层用于变化的图像,另一层用于位置。

你不应该奖励这个答案!我现在只是在附和 Seamus Campbell 的话;我只是稍微填写他的答案的细节。

好的,这是生成上面链接的电影的代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    // construct arr, an array of CGImage (omitted)
    // it happens I've got 5 images, the last being the same as the first
    self.images = [arr copy];
    // place sprite into the interface
    self.sprite = [CALayer new];
    self.sprite.frame = CGRectMake(30,30,24,24);
    self.sprite.contentsScale = [UIScreen mainScreen].scale;
    [self.view.layer addSublayer:self.sprite];
    self.sprite.contents = self.images[0];
}

- (void)animate {
    CAKeyframeAnimation* anim = 
        [CAKeyframeAnimation animationWithKeyPath:@"contents"];
    anim.values = self.images;
    anim.keyTimes = @[@0,@0.25,@0.5,@0.75,@1];
    anim.calculationMode = kCAAnimationDiscrete;
    anim.duration = 1.5;
    anim.repeatCount = HUGE_VALF;

    CABasicAnimation* anim2 = 
        [CABasicAnimation animationWithKeyPath:@"position"];
    anim2.duration = 10;
    anim2.toValue = [NSValue valueWithCGPoint: CGPointMake(350,30)];

    CAAnimationGroup* group = [CAAnimationGroup animation];
    group.animations = @[anim, anim2];
    group.duration = 10;

    [self.sprite addAnimation:group forKey:nil];
}
于 2013-04-15T23:29:00.837 回答