2012-03-02 7 views
13

CAKeyframeAnimations를 사용하여 레이어의 transform.rotationtransform.translation.x 속성에 애니메이션을 적용했지만 암시 적으로 transform 속성에 애니메이션을 적용하는 데 문제가 있습니다. 두 상태 사이에 애니메이션을해야하는 레이어가 있고 CABasicAnimation의 기본 보간은 완전히 틀리며 원하는 경로를 따르지 않습니다. CAKeyframeAnimation 구조, 또는 그래서 나는 생각했다. transform에 CAKeyframeAnimation을 사용하여 애니메이션을 적용하려고하면 다른 애니메이션이 실행되는 동안 뷰가 즉시 최종 변형에 스냅됩니다. 다음 함수의 첫 번째 절반을 제거하고 내 "변형"이벤트가 아래쪽의 CABasicAnimation을 사용하게하면 길게 따라 잘못 삽입 된 변형이 생깁니다.CAKeyframeAnimation으로 CATransform3D를 애니메이트하려면 어떻게해야합니까?

내 계층 대표는 구현 한 다음

- (id <CAAction>) actionForLayer:(CALayer *)layer forKey:(NSString *)event 
{  
    if ([event isEqualToString:@"transform"]) 
    { 
     CGSize startSize = ((CALayer *)self.layer.presentationLayer).bounds.size; 
     CGSize endSize = self.layer.bounds.size; 

     CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:event]; 
     animation.duration = 0.25; 

     NSMutableArray *values = [NSMutableArray array]; 

     int stepCount = 10; 
     for (int i = 0; i < stepCount; i++) 
     { 
      CGFloat p = i/(float)(stepCount - 1); 
      CGSize size = [self interpolateBetweenSize:startSize andSize:endSize percentage:p]; 
      CATransform3D transform = [self transformForSize:size]; 
      [values addObject:[NSValue valueWithCATransform3D:transform]]; 
     } 

     animation.values = values; 
     return animation; 
    } 

    // All other animations use this basic animation 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:event]; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    animation.removedOnCompletion = YES; 
    animation.fillMode = kCAFillModeForwards; 
    animation.duration = 0.25; 
    return animation; 
} 

변환 내

가 회전 다음에 번역,하지만 내 생각은 별도의 키 프레임 애니메이션이 번역을 통해 애니메이션과 회전 미친 초래 가진 그룹 애니메이션 도시. 나는 크기 & 변환이 내가 통과하는 p의 모든 값에 대해 정확하다는 것을 확인했다. 그리고 p는 0에서 1까지의 범위를 가진다.

기본값이 아닌 타이밍 함수를 설정하려고 시도했지만 설정을 시도했다 타이밍 함수의 배열, 나는 keyImes를 생략했습니다, 나는 repeatCount를 0으로 설정했습니다. removedOnCompletion = YES와 forwardMill의 fillMode는 아무 효과가 없습니다. 변형 키 프레임 애니메이션을 올바르게 생성하지 않습니까?

+1

성취하려는 정확한 효과를 분명히 할 수 있습니까? 당신은 회전으로 뒤 따르는 번역이라고 설명하지만, 코드에서 경계가 움직이는 것처럼 보입니다 - 맞습니까?이동/회전 애니메이션의 두 단계에서 연속적으로 경계가 커지거나 축소되는 레이어를 이동 한 다음 회전 시키시겠습니까? – GSnyder

+0

암묵적인 이유가 무엇입니까? 이 코드는 해커처럼 보입니다. 세밀한 제어가 필요한 경우 왜 애니메이션을 만들어서 레이어에 직접 추가하는 것인가? 또한 기본 애니메이션을 사용하려는 경우 위임 메서드에서'nil'을 반환하면됩니다. –

답변

0

이 기술은 iOS 3에서 작동했지만 iOS 5.0에서는 깨진 것 같습니다.

5.1 '마술처럼 수정'되면 iOS 5.0에서 버그로 보입니다. 나는 레이다 파일을 만들었지 만 현재 5.1에서 작동 중이다.

@Gsnyder : 일부 배경 : Clear와 비슷한 UI (Clear와 완전히 관련없는 무언가에 대한)를 실험 중이며이 부분은 http://blog.massivehealth.com/post/18563684407/clear입니다. 회전 & 번역의 필요성을 설명해야합니다.

저는 그때부터 측면에서 보았을 때 뷰가 N 레이어 (2 개가 아닌)로 세분되는 셔터 전환을 만들었습니다 : /////.

내 코드가 경계에 애니메이션을 적용하고 있지 않으므로 각 단계에서 크기를 사용하여 필요한 변환을 결정합니다.

@ Paul.s : Implicit는이 추상화를 소유하고있는보기 컨트롤러를 오염시키지 않고 레이어 클래스 자체 내에서이 추상화를 유지할 수있게합니다. 뷰 컨트롤러는 경계선을 바꿔 가면서 레이어가 적절히 움직여야합니다. 저는 뷰 자체가 그것을 다룰 수있을 때 수십 개의 커스텀 애니메이션을 가지고있는 뷰 컨트롤러의 팬이 아닙니다.

키 프레임 애니메이션을 사용해야합니다. 레이어 변환 사이의 기본 애니메이션 /과 _가 부정확 한 각도로 움직이므로 /// \ 레이어가 변형 전체에 정렬되지 않기 때문입니다. 키 프레임 애니메이션을 사용하면 모서리가 모두 제대로 움직이는 동안 모든 선이 올바르게 정렬됩니다.

나는 이것이 폐쇄 된 것으로 생각하고 있는데, 이것은 iOS 5.0의 버그 인 것으로 보이며 이후 수정되었습니다. 모두에게 감사드립니다.

0
(void)animateViewWith3DCurrentView:(UIView *)currentView withPoing:(CGPoint)movePoint 
{ 
    //flip the view by 180 degrees in its place first. 
    currentView.layer.transform =   CATransform3DRotate(currentView.layer.transform,myRotationAngle(180), 0, 1, 0); 

    //set the anchor point so that the view rotates on one of its sides. 
    currentView.layer.anchorPoint = CGPointMake(0.5, 0.5); 

    //Set up scaling 

    CABasicAnimation *resizeAnimation = [CABasicAnimation animationWithKeyPath:kResizeKey]; 

    //we are going to fill the screen here. So 423,337 
    [resizeAnimation setToValue:[NSValue valueWithCGSize:CGSizeMake(423, 337)]]; 
    resizeAnimation.fillMode   = kCAFillModeForwards; 
    resizeAnimation.removedOnCompletion = NO; 

    // Set up path movement 

    UIBezierPath *movePath = [UIBezierPath bezierPath]; 

    //the control point is now set to centre of the filled screen. Change this to make the path different. 
    // CGPoint ctlPoint  = CGPointMake(0.0, 0.5); 
    CGPoint ctlPoint  = CGPointMake(1024/2, 768/2); 

    //This is the starting point of the animation. This should ideally be a function of the frame of the view to be animated. Hardcoded here. 

    // Set here to get the accurate point.. 
    [movePath moveToPoint:movePoint]; 

    //The anchor point is going to end up here at the end of the animation. 
    [movePath addQuadCurveToPoint:CGPointMake(1024/2, 768/2) controlPoint:ctlPoint]; 

    CAKeyframeAnimation *moveAnim = [CAKeyframeAnimation animationWithKeyPath:kPathMovement]; 

    moveAnim.path    = movePath.CGPath; 
    moveAnim.removedOnCompletion = YES; 

    // Setup rotation animation 

    CABasicAnimation* rotateAnimation = [CABasicAnimation animationWithKeyPath:kRotation]; 
    //start from 180 degrees (done in 1st line) 
    CATransform3D fromTransform  = CATransform3DMakeRotation(myRotationAngle(180), 0, 1, 0); 
    //come back to 0 degrees 
    CATransform3D toTransform   = CATransform3DMakeRotation(myRotationAngle(0), 0, 1, 0); 

    //This is done to get some perspective. 
    CATransform3D persp1 = CATransform3DIdentity; 
    persp1.m34 = 1.0/-3000; 

    fromTransform = CATransform3DConcat(fromTransform, persp1); 
    toTransform = CATransform3DConcat(toTransform,persp1); 

    rotateAnimation.toValue    = [NSValue valueWithCATransform3D:toTransform]; 
    rotateAnimation.fromValue   = [NSValue valueWithCATransform3D:fromTransform]; 
    //rotateAnimation.duration   = 2; 
    rotateAnimation.fillMode   = kCAFillModeForwards; 
    rotateAnimation.removedOnCompletion = NO; 


    // Setup and add all animations to the group 

    CAAnimationGroup *group = [CAAnimationGroup animation]; 

    [group setAnimations:[NSArray arrayWithObjects:moveAnim,rotateAnimation, resizeAnimation, nil]]; 

    group.fillMode   = kCAFillModeForwards; 
    group.removedOnCompletion = NO; 
    group.duration   = 0.7f; 
    group.delegate   = self; 

    [group setValue:currentView forKey:kGroupAnimation]; 

    [currentView.layer addAnimation:group forKey:kLayerAnimation]; 
} 
관련 문제