2011-06-01 6 views
1

私はUIView(またはむしろCALayer)をアニメーション化しています。アニメーションの最後にはもはや見ることができません(3D変換を行い、yを90度回転させ、ドアがあなたに向かって開くと想像してください)。そのフレームはまだ画面上にあるという点で、技術的には「可視」です。CAAnimation - アニメーションの最後のフレームのプロパティを変更しますか?

このアニメーションの最後で、私はそのビューをanimationDidStop:finished:メソッドのスーパービューから削除します。

問題は、このビューが削除される前の元の変換されていない状態で表示されるという、簡単なフリッカーです。

これを修正する方法が不思議です。何も思いつきません。私はレイヤーの不透明度をアニメーション化しようとしましたが、それもうまくいきませんでした。まだちらつきが発生します。

アイデア?何かを提供することはできますか?

編集:ここにいくつかのコードが[サブビューremoveFromSuperview](さらに下にスクロールしてisHalfDone(あれば内部の行を探します)です。

- (void) pageOpenView:(UIView *)viewToOpen duration:(NSTimeInterval)duration pageTurnDirection:(PageTurnDirection) p{ 
    // Remove existing animations before stating new animation 
    [viewToOpen.layer removeAllAnimations]; 

    // Make sure view is visible 
    viewToOpen.hidden = NO; 

    // disable the view so it’s not doing anythign while animating 
    viewToOpen.userInteractionEnabled = NO; 

    float dir = p == 0 ? -1.0f : 1.0f; // for direction calculations 

    // create an animation to hold the page turning 
    CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    transformAnimation.removedOnCompletion = NO; 
    transformAnimation.duration = duration; 
    transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 

    CATransform3D startTransform = CATransform3DIdentity; 

    if (p == NEXT_PAGE) { 
     startTransform.m34 = 0.001f; 
    }else { 
     startTransform.m34 = -0.001f; 
    } 

    // start the animation from the current state 
    transformAnimation.fromValue = [NSValue valueWithCATransform3D:startTransform]; 
    // this is the basic rotation by 90 degree along the y-axis 
    CATransform3D endTransform = CATransform3DMakeRotation(3.141f/2.0f, 
                  0.0f, 
                  dir, 
                  0.0f); 
    // these values control the 3D projection outlook 
    if (p == NEXT_PAGE) { 
     endTransform.m34 = 0.001f; 
     endTransform.m14 = -0.0015f; 
    }else { 
     endTransform.m34 = -0.001f; 
     endTransform.m14 = 0.0015f; 
    } 


    transformAnimation.toValue = [NSValue valueWithCATransform3D:endTransform]; 


    // Create an animation group to hold the rotation 
    CAAnimationGroup *theGroup = [CAAnimationGroup animation]; 

    // Set self as the delegate to receive notification when the animation finishes 
    theGroup.delegate = self; 
    theGroup.duration = duration; 
    // CAAnimation-objects support arbitrary Key-Value pairs, we add the UIView tag 
    // to identify the animation later when it finishes 
    [theGroup setValue:[NSNumber numberWithInt:viewToOpen.tag] forKey:@"viewToOpenTag"]; // We set the tag to the page number 
    [theGroup setValue:[NSNumber numberWithInt: p] forKey:@"PageTurnDirection"]; 
    [theGroup setValue:[NSNumber numberWithBool:YES] forKey:@"isAnimationMidpoint"]; // i.e. is this the first half of page-turning or not? 

    // Here you could add other animations to the array 
    theGroup.animations = [NSArray arrayWithObjects:transformAnimation, nil]; 
    theGroup.removedOnCompletion = NO; 
    // Add the animation group to the layer 
    [viewToOpen.layer addAnimation:theGroup forKey:@"flipViewOpen"]; 
} 

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { 
    // Get the tag from the animation, we use it to find the animated UIView 
    NSNumber *tag = [theAnimation valueForKey:@"viewToOpenTag"]; 
    PageTurnDirection dir = [[theAnimation valueForKey:@"PageTurnDirection"] intValue]; 
    BOOL isHalfDone = [[theAnimation valueForKey:@"isAnimationMidpoint"] boolValue]; 

    UIView *toStack; // the stack the page has moved from 
    UIView *fromStack; // the stack the new page will go to. 
    int indexDirection; // will be either 1 or -1 

    int targetLastPageInStack; // the page number that wants to get added to its stack (i.e. either high or low) 

    // depending on which direction we are turning, we search a different stack 
    if (dir == NEXT_PAGE) { 
     fromStack = rightStack; 
     toStack = leftStack; 
     indexDirection = 1; 
     int lastPg; 

     UIView *lastPgInStack; 

     if ([fromStack.subviews count] > 0) { 
      lastPgInStack = [fromStack.subviews objectAtIndex:0]; 

      if ([lastPgInStack tag] == pageIndex) { 
       lastPg = pageIndex; // pagenr of currently last page in stack. 
      } 
      else { 
       // there was no last page, so the current page is the last page 
       lastPg = [lastPgInStack tag]; 
      } 
     }else { 
      lastPg = pageIndex; 
     } 


     targetLastPageInStack = lastPg + 2; 
    } 
    else { 
     fromStack = leftStack; 
     toStack = rightStack; 
     indexDirection = -1; 
     int lastPg; 
     UIView *lastPgInStack = [fromStack.subviews objectAtIndex:0]; 

     if ([lastPgInStack tag] == pageIndex-1) { 
      lastPg = pageIndex-1; // pagenr of currently last page in stack. 
     } 
     else { 
      // there was no last page, so the current page is the last page 
      lastPg = [lastPgInStack tag]; 
     } 

     targetLastPageInStack = lastPg - 2; 
    } 


    // different handling if the page turning is half done, or fully done. 
    if (isHalfDone) { 

     UIView *subview = [fromStack viewWithTag:[tag intValue]]; 

     if (flag) { 
      // Now we just hide the animated view since 
      // animation.removedOnCompletion is not working 
      // in animation groups. Hiding the view prevents it 
      // from returning to the original state and showing. 

      subview.hidden = YES; 
      [subview removeFromSuperview]; // REMOVE THE ANIMATED PAGE FROM THE STACK 


      // now create one on that stack 
      if ((dir == NEXT_PAGE && targetLastPageInStack <= self.endPageIndex) || (dir == PREV_PAGE && targetLastPageInStack >= self.startPageIndex)) { 

       BODBookPage *newPage = [BODBookPage pageInBook:&myDocumentRef pageNum:targetLastPageInStack frame:fromStack.bounds] ; 
       newPage.hidden = NO; 
       [fromStack insertSubview:newPage atIndex:0]; 
      } 

     } 

     // now create the view for the page that'll be turned over and add it to the right stack. Probably set it to hidden as well. 
     BODBookPage *newPage = [BODBookPage pageInBook:&myDocumentRef pageNum:[tag intValue] + 1*indexDirection frame:toStack.bounds] ; 
     newPage.hidden = YES; 
     [toStack addSubview:newPage]; 
     [self pageCloseView:newPage duration:turningTime/2.0f pageTurnDirection:dir]; 
    } 
    else { 
     // we just animated the page turning from up to over 

     // now have to remove the most distant view, so the view at subview index 0. We do this to keep memory usage low. 
     if ([toStack.subviews count] > 1) { 
      [(UIView*)[toStack.subviews objectAtIndex:0] removeFromSuperview]; 
     } 


     pageIndex = pageIndex + 2*indexDirection; 
    } 

} 
+0

この問題は、[これも同様]と同じようです(http://stackoverflow.com/questions/262508/catransition-showing-a-single-frame-from-the-end-of-the-transition - 前に戻る) – horseshoe7

答えて

3

これは、質問への答えだった:それはanimation fillMode propertyについてです

+0

+1あなたが答えを投稿しました。 – Krishnan

+1

必須です! "助けてください、助けてください、助けてください!私のためにコードを書いてくださいしてください... "と続きましたが、理由は何も説明されていません。 – horseshoe7

+0

あなたは答えとしてそれを受け入れることもできます。それは答えの信頼性を高めるでしょう – Krishnan