2011-06-01 72 views
1

我在動畫UIView(或者說它的CALayer),並且在動畫結束時它不再可見(我做了一個3D變換,以便它圍繞y旋轉90°,想象一個開向你的門),儘管從技術上講,它的框架仍然在屏幕上,因此在技術上「可見」。CAAnimation - 在動畫的最後一幀中更改屬性?

在動畫結束時,我從animationDidStop:finished:方法的superview中移除了該視圖。

問題是,有一個簡短的閃爍,您可以在它被移除之前以原始未轉換狀態看到此視圖。

我想知道如何解決這個問題。我不知道。我嘗試將圖層的不透明度設置爲動畫效果,但這也不起作用。閃爍仍然發生。

任何想法?我可以提供任何東西,或者可能有人在這裏遇到過這個問題嗎?

編輯:下面是一些代碼(進一步向下滾動,並查找線內,如果(isHalfDone)其中子視圖removeFromSuperview];

- (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 -foreign-the-ani) – horseshoe7 2011-06-01 13:10:38

回答

3

這是問題的答案:它是關於animation fillMode property

+0

+1。好的你發佈了答案。 – Krishnan 2011-06-07 10:20:44

+1

一定要!比寫一句「幫助我,幫助我,幫助我!」的人更加惱人!只需爲我寫代碼請......「後面跟着」我修好了「,沒有解釋爲什麼...... – horseshoe7 2011-06-17 13:07:19

+0

你也可以接受它作爲答案。這會增加答案 – Krishnan 2011-06-17 13:53:57