2

여러개의 루프를 반복하여 각각의 애니메이션을 수행하려고합니다. 그러나 모든 애니메이션이 끝났음을 알고 싶습니다. 애니메이션 반복이 끝나면 함수를 호출하는 가장 좋은 방법은 무엇입니까? 또는 모든 것이 완료 될 때까지 기다릴 수있는 방법이 있습니까?UIView 애니메이션 반복을 마칠 때까지 기다리는 가장 좋은 방법은 무엇입니까?

setAnimationDidStopSelector을 사용해 보았지만 시작되지 않습니다. 이 경우 게임 보드에서 "칩"을 지우고 사라지게하여 제거합니다 (NumberedChipView는 UIView의 하위 클래스 임). 칩이 보드에서 빠져 나올 때까지 플레이를 계속할 수 없습니다.

[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationDelegate: self]; 
[UIView setAnimationDidStopSelector:@selector(animationDidStop)]; 

// clear chips 
for (HexagonalTile *aTile in tilesToClear) { 

    NumberedChipView *chipView = [self chipViewForColumn:aTile.column andRow:aTile.row]; 

    [UIView animateWithDuration:0.5 delay:0.3 options:UIViewAnimationCurveLinear animations:^{ 
     chipView.alpha = 0.0; 
    } 
     completion:^(BOOL finished){ 

     if (finished) { 

      [chipView removeFromSuperview]; 
      [self.chipViews removeObject:chipView]; 

     } 
    }]; 
} 

[UIView commitAnimations]; 

는 또한 아무 소용 CATransaction을 시도 :

[CATransaction begin]; 

[CATransaction setCompletionBlock:^{ 
    [self animationFinished]; 
}]; 

// clear chips 
for (HexagonalTile *aTile in tilesToClear) { 

    NumberedChipView *chipView = [self chipViewForColumn:aTile.column andRow:aTile.row]; 

    [UIView animateWithDuration:0.5 delay:0.3 options:UIViewAnimationCurveLinear animations:^{ 
     chipView.alpha = 0.0; 
    } 
     completion:^(BOOL finished){ 

     if (finished) { 

      [chipView removeFromSuperview]; 
      [self.chipViews removeObject:chipView]; 

      //NSLog(@"clearing finished"); 
     } 
    }]; 
} 

[CATransaction commit]; 

업데이트 :

지금 발사 셀렉터를 얻을 수 있습니다, 그러나 그것은 애니메이션의 루프 기다리지 않습니다

끝내기 위해.

[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:)]; 

답변

0

여기 나를 위해 일하고 결국거야. UIView animateWithDuration 메서드가 begin/commit 섹션에 연결되지 않았다는 것을 깨달았습니다. 오히려 begin/commit 섹션은 "암시 적"애니메이션 작업 영역을 표시하므로 애니메이션 내에서 속성을 설정할 수 있으며 암시 적으로 애니메이션이 적용됩니다.

예를 들어 아래 애니메이션에서 나는 단순히 chipView의 alpha 속성을 "0.0"으로 설정하고 chipView (UIView)는 암시 적으로 사라지도록 애니메이션되었습니다.

[UIView beginAnimations:@"tilescleared" context:nil]; 
[UIView setAnimationDelegate: self]; 
[UIView setAnimationDelay:0.3]; 
[UIView setAnimationDuration:0.5]; 
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 

for (HexagonalTile *aTile in tilesToClear) { 

    NumberedChipView *chipView = [self chipViewForColumn:aTile.column andRow:aTile.row]; 

    chipView.alpha = 0.0; 

} 

[UIView commitAnimations]; 

내 animationDidStop 메서드에서 "정리"를 수행하고 수퍼 뷰에서 칩을 제거합니다. 이 animationDidStop 메서드는 루프의 모든 chipView 애니메이션이 끝났을 때만 발생합니다. 이는 내가 알아 내려고 시도하는 까다로운 작업입니다.

1

for 루프는 동일한 지연 시간과 같은 지속 시간으로 모든 애니메이션을 실행하므로 동시에 시작하고 종료합니다.

완성 방법은 각 애니메이션마다 한 번 호출됩니다.

루프를 입력하기 전에 카운터를 0으로 설정하도록 코드를 약간 재 작성하고 각 단계마다 코드를 증가시킬 수 있습니다. 인덱스가 배열 수보다 작 으면 nil 완료 블록을 전달하십시오. 일단 인덱스 == 배열 수, 당신은 마지막 항목에있어, 그래서 마지막 애니메이션이 완료되면 호출하고자하는 코드와 함께 완료 블록을 전달하십시오. 인덱스 값에 따라 지연 양을 증가시켜, 다른 시간에 각각의 애니메이션 시작을 만들기 위해이 인덱스 접근 방법을 사용할 수 있습니다

참고 :

delay = .3 + (0.5 * index); 
+0

여기서 단점은 완성 블록이 애니메이션이 별도의 스레드에서 발생하여 동시에 발생한다는 것입니다. 따라서 지연 변수로 원 자성을 보장해야합니다. 나는 이것과 같은 것을 시도했고 그것은 단지 매달릴 것이다. –

+0

이 애니메이션 동시성에 대한 Apple 문서 (https://developer.apple.com/library/ios/#documentation/windowsviews/conceptual/viewpg_iphoneos/AnimatingViews/AnimatingViews)를 참조하십시오.html # // apple_ref/doc/uid/TP40009503-CH6-SW3 –

+0

물론 UIView beginAnimation/commitAnimation 메소드는 이전 스타일이며, Apple docs는 블록 기반 메소드가 선호된다고 말합니다. 그러나이 경우 블록 기반 방법을 작동시키는 방법을 실제로 파악할 수 없었습니다. –

관련 문제