2012-05-29 58 views
0

我試圖一個接一個地執行多個UIView動畫。但是,我聽說一個接一個地執行多個UIView動畫是不好的做法,而我應該使用Core Animation。我試過這個代碼:多個UIView動畫

//First Animation 
[UIView beginAnimations:@"animation1" context:nil]; 
[UIView setAnimationDuration:2]; 
nwView.backgroundColor = [UIColor redColor]; 
nwView.frame = CGRectMake(CGRectGetMidX(screenSize), 
          CGRectGetMinY(screenSize), 
          width, 
          height); 
nwView.transform = CGAffineTransformMakeRotation(45.0f); 
[UIView commitAnimations]; 

//Second Animation 
[UIView beginAnimations:@"second animation" context:nil]; 
[UIView setAnimationDuration:2]; 

nwView.transform = CGAffineTransformMakeScale(0.5, 0.33); 
nwView.backgroundColor = [UIColor purpleColor]; 

[UIView commitAnimations]; 

但它只做第二個動畫。我知道這個問題類似於UIView two animations coexisting,但它有一個稍微不同的上下文。

回答

4

我不認爲使用UIView塊在一行中做2個動畫有什麼問題。只要確保你在第一個動畫的補全區塊中開始你的第二個動畫。

沒有塊(你的例子)它不工作,因爲你將不得不設置委託給動畫或設置選擇器setAnimationDidStopSelector。你應該開始第二個動畫。

但是,用塊做動畫沒什麼不妥(這是首選的方法)。

+0

完全不正確的。如果被中斷,例如用戶離開應用等,塊基動畫的完成塊將不會被調用。 – durazno

3

如果您正在尋找多個動畫,那麼這不是一種方法。您發佈的代碼幾乎同時執行,這意味着動畫將在大約同一時間執行。

相反,你應該做的是設置第一個動畫的委託,然後做第一個動畫。然後,當爲第一個動畫調用animationDidStop方法時,應該執行第二個動畫。這確保他們是一個接一個。

這是你如何做,假設你調用doMyAnimations開始動畫。

-(void)doMyAnimations{ 
    //First Animation 
    [UIView beginAnimations:@"animation1" context:nil]; 
    [UIView setAnimationDuration:2]; 
    [UIView setAnimationDelegate:self]; 
    nwView.backgroundColor = [UIColor redColor]; 
    nwView.frame = CGRectMake(CGRectGetMidX(screenSize), 
           CGRectGetMinY(screenSize), 
           width, 
           height); 
    nwView.transform = CGAffineTransformMakeRotation(45.0f); 
    [UIView commitAnimations]; 
} 

- (void)animationWillStart:(NSString *)animationID context:(void *)context{ 
} 

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{ 
    if([animationID isEqualToString:@"animation1"]){ 
     //Second Animation 
     [UIView beginAnimations:@"second animation" context:nil]; 
     [UIView setAnimationDuration:2]; 

     nwView.transform = CGAffineTransformMakeScale(0.5, 0.33); 
     nwView.backgroundColor = [UIColor purpleColor]; 

     [UIView commitAnimations]; 
    } 
} 

請記住,nwView必須在整個課程中都可以訪問。如果不是,您可以將其設爲實例變量,或者在animationDidStop方法中找到另一種方法來訪問它。

+0

LocoMike建議使用animateWithDuration:動畫:完成更簡潔。這正是完成模塊所打算的那種情況。 –

+0

是的,我看到我的LocoMikes回答。我想我可能會提供一種替代方式。 –

1

您可以將塊用於此目的並獲得非常乾淨的結果。

NSMutableArray* animationBlocks = [NSMutableArray new]; 

typedef void(^animationBlock)(BOOL); 

// getNextAnimation 
// removes the first block in the queue and returns it 
animationBlock (^getNextAnimation)() = ^{ 
    animationBlock block = (animationBlock)[animationBlocks firstObject]; 
    if (block){ 
     [animationBlocks removeObjectAtIndex:0]; 
     return block; 
    }else{ 
     return ^(BOOL finished){}; 
    } 
}; 

//add a block to our queue 
[animationBlocks addObject:^(BOOL finished){; 
    [UIView animateWithDuration:1.0 animations:^{ 
     //...animation code... 
    } completion: getNextAnimation()]; 
}]; 

//add a block to our queue 
[animationBlocks addObject:^(BOOL finished){; 
    [UIView animateWithDuration:1.0 animations:^{ 
     //...animation code... 
    } completion: getNextAnimation()]; 
}]; 

//add a block to our queue 
[animationBlocks addObject:^(BOOL finished){; 
    NSLog(@"Multi-step Animation Complete!"); 
}]; 

// execute the first block in the queue 
getNextAnimation()(YES); 

來自http://xibxor.com/objective-c/uiview-animation-without-nested-hell/