Fill Color Animation Flickers when calling block in animation did stop

前端 未结 1 1883
别跟我提以往
别跟我提以往 2021-01-13 21:43

Im having trouble figuring out why the animation is flickering from the fromValue to the toValue after my animation block is complete. I know that after you complete an anim

1条回答
  •  一整个雨季
    2021-01-13 21:43

    To answer your first question

    layoutSubviews will only be called once per run-loop. You can call [self setNeedsLayout] as much as you want without worrying about taking a performance hit laying out your views needlessly.

    Referenced From: Kubicek, Jim. "Abusing UIView." OCT 11TH, 2012. http://jimkubicek.com/blog/2012/10/11/using-uiview/

    To answer your second question, you are right about why it is flickering. The problem is that there is no guarantee that the animationDidStop callback method will be called before the layer's appearance is reset.

    There are a couple of ways to fix this, the following way just involves adding some extra code without changing your existing code.

    //kCAFillModeForwards: the animatable properties take on the end value once it has finished
    [strokeAnimation setFillMode:kCAFillModeForwards];
    [strokeAnimation setRemovedOnCompletion:NO];
    [fillAnimation setFillMode:kCAFillModeForwards];
    [fillAnimation setRemovedOnCompletion:NO];
    [group setFillMode:kCAFillModeForwards];
    [group setRemovedOnCompletion:NO];
    
    [self.checkmarkLayer addAnimation:group forKey:nil];
    

    When a CAAnimation completes, it removes itself from the layer and causes the layer to reset, so the first thing we will do is stop the animation from being removed.

    - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
    {
        animationCompletionBlock theBlock = [theAnimation valueForKey: kAnimationCompletionBlock];
        if (theBlock)
            theBlock();
    
    [self.checkmarkLayer removeAllAnimations];
    

    }

    When the animationDidStop method is called, we set the layer's properties like before, then we remove the animations from the layer.

    One more thing to think about is that when you change a CALayer's appearance, it gets implicitly (automatically) animated. So when you setup the completion block, you want to explicitly tell core animation not to animate

    animationCompletionBlock block;
            block = ^(void){
                [CATransaction begin];
                [CATransaction setDisableActions:YES];
                [self.checkmarkLayer setFillColor:[UIColor whiteColor].CGColor];
                [CATransaction commit];
            };
    

    0 讨论(0)
提交回复
热议问题