2013-04-15 34 views
2

標題可能不是很清楚,但我想要做的是讓UIImageView顯示一系列圖像(有點像gif),我通過將animationImages設置爲一組圖像,然後調用[imageView startAnimating]; 。這工作正常。我也有用CABasicAnimation來移動UIImageView的代碼,而且這個動畫代碼也能正常工作。但是,當我嘗試同時爲UIImageView的圖像製作動畫並嘗試移動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"]; 

所以GIF效果不工作時UIImageView的位置正在動畫化。我的問題是我該如何做到這一點,所以當UIImageView的位置被動畫化時,UIImageView會循環顯示一組圖像。

+0

添加了一些細節和說明視頻到我的答案。 – matt

回答

5

這是炒作,我沒有測試過這種想法可言,但你有沒有考慮實現在同一圖像動畫時尚你在動畫的位置,與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]; 
} 
+0

如何將一個CGImage對象數組存儲在一個數組中?我只是把它們投給'(id)'? – pasawaya

+0

是的。你可以通過'[myImage CGImage]'從'UIImage'獲得'CGImage'。 –

+0

我非常同意這種方法,我完全重寫了我自己的答案! – matt

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]; 
     } 
    }]; 

也許您遇到的問題是因爲兩個動畫都在同一個線程上?

1

這不是製作精靈的好方法。我可以堅持認爲你應該使用OpenGL,但可能沒有必要去那麼遠;你可以用一個圖層的核心動畫來完成所有的工作,我想你會比嘗試使用完整的UIImageView更好。

使用圖層的Core Animation,我可以在打開和閉合嘴巴的同時使這個PacMan sprite在屏幕上生成動畫;這不是你想到的那種東西嗎?

enter image description here

下面是該動畫的視頻!

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

然而實際的代碼創建動畫是非常簡單的:只有兩個層動畫(核心動畫),一個用於改變圖像,另一個用於位置。

您應該不是獎勵此答案獎勵!我現在只是迴應西莫斯坎貝爾說的話;我只是填寫他的答案的細節。

好了,所以這裏的生成上面鏈接電影代碼:

- (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]; 
} 
+0

對不起,我不接受。我試圖按照鏈接(最初看起來很有希望),但我做不到。我會嘗試你的新代碼。謝謝! – pasawaya

+0

只是一個問題:什麼是CALayer的「索引」屬性? – pasawaya

+0

這就像我指出的教程中的'sampleIndex'屬性。基本上,隨着'index'的變化,CALayer子類將通過重新繪製序列中的下一幅圖像來進行響應。 – matt

1

你的「基本」問題,在此開始行:

CABasicAnimation *moveAnimation = [CABasicAnimation animation]; 

CABasicAnimation對象uses only a single keyframe。這意味着您正在動畫的圖層的內容會被繪製一次,然後該圖像將用於動畫的持續時間。

使用CAKeyframeAnimation作爲Seamus的建議是一種解決問題的方法 - 關鍵幀動畫將多次重繪動畫層的內容,因此爲每個關鍵幀繪製連續的圖像將動畫化內容以及位置。