iOS CAKeyFrameAnimation Scaling Flickers at animation end

后端 未结 3 2175
刺人心
刺人心 2021-02-06 12:29

In another test of Key Frame animation I am combining moving a UIImageView (called theImage) along a bezier path and scaling larger it as it moves, resulting in a 2

3条回答
  •  天涯浪人
    2021-02-06 13:12

    I was experimenting with some CAAnimations this week and was noticing that there was a flickering at the end of my animations. In particular, I would animation from a circle to a square, while changing the fillColor as well.

    Each CAAnimation has a property called removedOnCompletion which defaults to YES. This means that the animation will disappear (i.e. transitions, scales, rotations, etc.) when the animation completes and you'll be left with the original layer.

    Since you already have set your removedOnCompletion properties to NO, I would suggest trying to shift your execution of your animations to use CATransactions, instead of delegates and animationDidStop...

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    [CATransaction setCompletionBlock: ^{ theImage.transform = ...}];
    
    // ... CAAnimation Stuff ... //
    
    [CATransaction commit];
    

    You put the transaction's completion block call before you create your animations, as per: http://zearfoss.wordpress.com/2011/02/24/core-animation-catransaction-protip/

    The following is from one of my methods:

    [CATransaction begin];
    CABasicAnimation *animation = ...;
    animation.fromValue = ...;
    animation.toValue = ...;
    [CATransaction setCompletionBlock:^ { self.shadowRadius = _shadowRadius; }];
    [self addAnimation:animation forKey:@"animateShadowOpacity"];
    [CATransaction commit];
    

    And, I constructed this animation and it works fine for me with no glitches at the end: The setup and trigger are custom methods I have in a window, and i trigger the animation on mousedown.

    UIImageView *imgView;
    UIBezierPath *animationPath;
    
    -(void)setup {
        canvas = (C4View *)self.view;
        imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"img256.png"]];
        imgView.frame = CGRectMake(0, 0, 128, 128);
        imgView.center = CGPointMake(384, 128);
        [canvas addSubview:imgView];
    
    }
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        [UIImageView animateWithDuration:2.0f animations:^{
            [CATransaction begin];        
            CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
            pathAnimation.duration = 2.0f;
            pathAnimation.calculationMode = kCAAnimationPaced;
            animationPath = [UIBezierPath bezierPath];
            [animationPath moveToPoint:imgView.center];
            [animationPath addLineToPoint:CGPointMake(128, 512)];
            [animationPath addLineToPoint:CGPointMake(384, 896)];
            pathAnimation.path = animationPath.CGPath;
            pathAnimation.fillMode = kCAFillModeForwards;
            pathAnimation.removedOnCompletion = NO;
            [imgView.layer addAnimation:pathAnimation forKey:@"animatePosition"];
            [CATransaction commit];
    
            CGFloat scaleFactor = 2.0f;
            CGRect newFrame = imgView.frame;
            newFrame.size.width *= scaleFactor;
            newFrame.size.height *= scaleFactor;
            newFrame.origin = CGPointMake(256, 0);
            imgView.frame = newFrame;
            imgView.transform = CGAffineTransformRotate(imgView.transform,90.0*M_PI/180);
    
        }];
    }
    

提交回复
热议问题