2013-02-27 3 views
0

키 프레임에 애니메이션을 적용 할 때 분명하지 않은 것처럼 보입니다. CAKeyframeAnimation 설명서에 언급 된 Apple의 MoveMe을 비롯한 많은 코드 샘플을 살펴 봤지만 내가보기에는 불일치가 있습니다.장치를 회전 할 때까지 CAKeyframeAnimation이 애니메이션으로 표시되지 않습니다.

나는 CGMutablePathRef 다음에 CAKeyframeAnimation을 만들고 경로를 따라 이미지보기를 애니메이션으로 설정합니다. 완료되면보기를 제거 할 수 있도록 애니메이션 그룹이 만들어집니다.

아직 내 애니메이션이 표시되지 않습니다. 장치를 회전 할 때까지. 뷰를 다시 레이아웃하면 애니메이션이 킥 스타트하게됩니다. 나는 [theImageView setNeedsDisplay] 또는 심지어 setNeedsLayout과 같은 명백한 시도를했고 컨테이너보기에서도 마찬가지였다. 아직, 내가 필요로 할 때 여전히 작동하지 않습니다. 그들은 장치를 돌릴 때만 나타난다.

다음에서 -cgPathFromArray:은 내부 opcode의 NSArray을 취하여 CGPathRef으로 변환합니다. 디바이스를 회전 시키면 애니메이션이 프로그래밍 된 경로를 따라 표시되기 때문에 올바른 것으로 검증됩니다.

- (void) animateImage: (NSString*) imageName 
       onPath: (NSArray*) path 
     withDuration: (NSString*) duration 
{ 
    if (self.sceneView) 
    { 
     CGMutablePathRef animationPath = [self cgPathFromArray: path]; 

     if (animationPath) 
     { 
      UIImage* image  = [self findImage: imageName]; 

      if (image) 
      { 
       UIImageView* imageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, image.size.width, image.size.height)]; 

       if (imageView) 
       { 
        CAKeyframeAnimation* keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath: @"position"]; 

        imageView.image = image; 

        [self.sceneView addSubview: imageView]; 

        keyFrameAnimation.removedOnCompletion = YES; 
        keyFrameAnimation.fillMode    = kCAFillModeForwards; 
        keyFrameAnimation.duration    = duration.floatValue; 
        keyFrameAnimation.timingFunction  = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear]; 
        keyFrameAnimation.repeatCount = 0; 

        keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 

        [keyFrameAnimation setPath: animationPath]; 

        //group animation with termination block to cleanup 
        CAAnimationGroup* group  = [CAAnimationGroup animation]; 

        group.duration    = keyFrameAnimation.duration; 
        group.removedOnCompletion = YES; 
        group.fillMode    = kCAFillModeForwards; 
        group.animations   = @[keyFrameAnimation]; 

        CorpsAnimationCompletionBlock theBlock = ^void(void) 
        { 
         [imageView removeFromSuperview]; 
        }; 

        [group setValue: theBlock 
          forKey: kCorpsAnimationCompletionBlock]; 

        group.delegate = self; 

        [imageView.layer addAnimation: group 
              forKey: nil]; 
       } 
      } 
     } 
    } 
} 

누구든지 도움이 될 수 있습니까?

답변

1

표시되는 레이어 트리에 레이어가 추가 된 동일한 트랜잭션의 레이어에 애니메이션을 추가하기 때문에 문제가 발생했을 수 있습니다. Core Animation은 아직 커밋되지 않은 레이어에 애니메이션을 첨부하는 것을 좋아하지 않습니다. 레이어를 추가 한 후 [CATransaction flush]을 수행하면이 문제를 해결할 수 있습니다.

과도한 중첩 때문에 코드를 보는 것이 다소 어렵습니다. 더 빨리 읽을 수 있도록 조기 반품을 고려하십시오.

또한 사용자는 -[UIImage initWithImage:] 이니셜 라이저가 생성하는 것과 동일한 프레임을 명시 적으로 생성하고 있습니다.

애니메이션 그룹을 사용하고 단순히 애니메이션의 끝에 블록을 실행할 수 있도록 위임자를 설정하는 경우 더 쉬운 방법이 있습니다. CATransaction을 시작하고 트랜잭션의 완료 블록을 설정 한 다음 애니메이션을 추가 한 다음 트랜잭션을 커밋 할 수 있습니다. 따라서

:

- (void) animateImage:(NSString *)imageName onPath: (NSArray *)path 
    withDuration: (NSString *)duration 
{ 
    if (!self.sceneView) 
     return; 

    CGMutablePathRef animationPath = [self cgPathFromArray:path]; 
    if (!animationPath) 
     return; 

    UIImage *image = [self findImage:imageName]; 
    if (!image) 
     return; 

    UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 
    [self.sceneView addSubview: imageView]; 

    // commit the implicit transaction so we can add an animation to imageView. 
    [CATransaction flush]; 

    [CATransaction begin]; { 
     [CATransaction setCompletionBlock:^{ 
      [imageView removeFromSuperview]; 
     }]; 

     CAKeyframeAnimation *animation = [CAKeyframeAnimation 
      animationWithKeyPath:@"position"]; 
     animation.duration = duration.floatValue; 
     animation.timingFunction = [CAMediaTimingFunction 
      functionWithName:kCAMediaTimingFunctionLinear]; 
     animation.path = animationPath; 
     [imageView.layer addAnimation:animation forKey:animation.keyPath]; 
    } [CATransaction commit]; 
} 
+0

간단히 추가'[CATransaction 플러시]'트릭을했다. 감사! (끝 부분에 내 단일 계산서를 보관하겠습니다.) –

+0

@ Martin-GillesLavoie, 아니요, [속해 있지 않습니다] (http : //softwareengineering.stackexchange. co.kr/q/18454/146874)! –