Create an endless animation with pop?

我与影子孤独终老i 提交于 2019-12-25 03:45:37

问题


When using the Coreanimation framework I can set an animation to repeat. I want to set a button to an "attract attention" mode which should make him grow and shrink by a small amount to get the users attention.

I already chained the grow and shrink animations via completion blocks. The question is if and how I can start the first animation from the second animation's completion block.

I do get the following warning which does make sense. What is an elegant solution to this problem? I'm not a fan of creating timers for stuff like this.

Capturing 'scaleAnimation' strongly in this block is likely to lead to a retain cycle

- (void)attractAttention:(BOOL)flag{
    _attractAttention = flag;
    float resizeValue = 1.2f;

        // Grow animation
    POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    scaleAnimation.fromValue  = [NSValue valueWithCGSize:CGSizeMake(1.0f, 1.0f)];
    scaleAnimation.toValue  = [NSValue valueWithCGSize:CGSizeMake(resizeValue, resizeValue)];
    scaleAnimation.completionBlock = ^(POPAnimation *anim, BOOL finished) {
            // Grow animation done
        POPSpringAnimation *scaleAnimationDown = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
        scaleAnimationDown.fromValue  = [NSValue valueWithCGSize:CGSizeMake(resizeValue, resizeValue)];
        scaleAnimationDown.toValue  = [NSValue valueWithCGSize:CGSizeMake(1.0f, 1.0f)];

        scaleAnimationDown.completionBlock = ^(POPAnimation *anim, BOOL finished) {
                // Shrink animation done
            if (_attractAttention) {
                [self.layer pop_addAnimation:scaleAnimation forKey:@"scaleUpAnimation"];
            }
        };

        [self.layer pop_addAnimation:scaleAnimationDown forKey:@"scaleDownAnimation"];
    };

    [self.layer pop_addAnimation:scaleAnimation forKey:@"scaleUpAnimation"];
}

Edit:

I also tried to create a weak reference of the animation. This removes the error, but the animations do not work anymore:

__weak typeof(scaleAnimation) weakAnimation = scaleAnimation;

回答1:


You can also use the properties autoreveres and repeatCount to achieve the same result without use blocks. It reduces the complexity:

POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(0.5, 0.5)];
scaleAnimation.springBounciness = 0.f;
scaleAnimation.autoreverses = YES;
scaleAnimation.repeatCount=HUGE_VALF;
[layer pop_addAnimation:scaleAnimation forKey:@"scale"];

Even better, if you check this class https://github.com/facebook/pop/blob/master/pop/POPAnimation.h you will see there is a repeatForever property, so you could replace repeatCount by it:

scaleAnimation.repeatForever=YES;



回答2:


Edited: Do not use this solution. The POP framework has been updated with a “repeat” flag. It was not available when I first encountered this problem.


I solved it by a very easy work around:

- (void)attractAttention:(BOOL)flag{
    _attractAttention = flag;
    if (_attractAttention){
        [self animatePop];
    }
}


- (void)animatePop{
    float resizeValue = 1.2f;

        // Grow animation
    POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];

    scaleAnimation.fromValue  = [NSValue valueWithCGSize:CGSizeMake(1.0f, 1.0f)];
    scaleAnimation.toValue  = [NSValue valueWithCGSize:CGSizeMake(resizeValue, resizeValue)];
    scaleAnimation.completionBlock = ^(POPAnimation *anim, BOOL finished) {
            // Grow animation done
        POPSpringAnimation *scaleAnimationDown = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
        scaleAnimationDown.fromValue  = [NSValue valueWithCGSize:CGSizeMake(resizeValue, resizeValue)];
        scaleAnimationDown.toValue  = [NSValue valueWithCGSize:CGSizeMake(1.0f, 1.0f)];

        scaleAnimationDown.completionBlock = ^(POPAnimation *anim, BOOL finished) {
                // Shrink animation done
            if (_attractAttention) {
                [self animatePop];
            }
        };

        [self.layer pop_addAnimation:scaleAnimationDown forKey:@"scaleDownAnimation"];
    };

    [self.layer pop_addAnimation:scaleAnimation forKey:@"scaleUpAnimation"];
}


来源:https://stackoverflow.com/questions/25954443/create-an-endless-animation-with-pop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!