facebookarchive / pop

An extensible iOS and OS X animation library, useful for physics-based interactions.
Other
19.66k stars 2.88k forks source link

Multiple animations in same view hierarchy are interfering. #305

Closed cassidyclawson closed 8 years ago

cassidyclawson commented 8 years ago

pop_problem_v01

As you can see in the gif above, I have two independent POP animations in the same view hierarchy.

The first animation is the caption swipe triggered by a touch gesture. The second is the recursive blooping of the "guess" button.

For some reason that I can't understand, the caption change animation can disrupt the recursive bloop animation, resulting in an unwanted change of size and origin of the button. This happens even if I use a basic UIView animation for the button bloop.

Thanks to everyone who has worked on this project. It really is cool.

Any ideas?

The swipe animation:

- (void)cyclePrompt
{    
    // Springy snap back right
    POPSpringAnimation *animRight = [POPSpringAnimation animation];
    animRight.property = [POPAnimatableProperty propertyWithName:kPOPLayerTranslationX];
    animRight.toValue = @(0);
    animRight.springBounciness = 20.f;
    animRight.springSpeed = 20.f;

    // Basic left
    POPBasicAnimation *animLeft = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerTranslationX];
    animLeft.toValue = @(-5.f);
    animLeft.duration = 0.05;
    animLeft.completionBlock = ^(POPAnimation *animation, BOOL finished) {
        [self.faceView.layer pop_addAnimation:animRight forKey:@"right"];
    };

    [self.faceView.layer pop_addAnimation:animLeft forKey:@"left"];
}

And the recursive bloop (this is called over and over using a timer)

+ (void)bloopView:(UIView *)view WithScale:(float)scale growDuration:(float)growTime actionAtPeak:(void (^)(void))actionBlock
{
    POPSpringAnimation *animShrinkBounce = [POPSpringAnimation animation];
    animShrinkBounce.property = [POPAnimatableProperty propertyWithName:kPOPLayerScaleXY];
    animShrinkBounce.toValue = [NSValue valueWithCGSize:CGSizeMake(1, 1)];;
    animShrinkBounce.springBounciness = 5.f;
    animShrinkBounce.springSpeed = 12.f;
    animShrinkBounce.dynamicsTension = 1000;

    POPBasicAnimation *animGrow = [POPBasicAnimation animation];
    animGrow.property = [POPAnimatableProperty propertyWithName:kPOPLayerScaleXY];
    animGrow.toValue = [NSValue valueWithCGSize:CGSizeMake(scale, scale)];
    animGrow.duration = growTime;
    animGrow.completionBlock = ^(POPAnimation *anim, BOOL finished) {
        [view.layer pop_addAnimation:animShrinkBounce forKey:@"bloopGrow"];
        if(actionBlock) {
            actionBlock();
        }
    };
    [view.layer pop_addAnimation:animGrow forKey:@"bloopShrinkBounce"];
}
grp commented 8 years ago

If this also happens if you don't use an animation or if you use a non-Pop animation, it's probably not an issue with Pop. In fact, Pop doesn't do anything more complex than setting the view or layer properties being animate. It might be good to investigate without animations at all, just by setting the layer properties.

It'll be hard for me to help debug further without a sample project to look at, unfortunately.

cassidyclawson commented 8 years ago

Thanks for the prompt reply @grp.

It does indeed happen with UIView animations. It does not happen without animations.

Do you have any intuition as to what could be happening under the hood and what I could start looking for?

grp commented 8 years ago

Pop is just setting values over time. You could try setting values over time in your own code and see if you can isolate the issue that way? You should then be able to clearly see what changes when it doesn't work.

cassidyclawson commented 8 years ago

Thanks for the tip.

In case anyone finds this issue and faces a similar problem... this problem was caused by a method changing the frame of the animated object while the animation was in progress. I was able to find it by creating overrides for setCenter, setFrame and setBounds, adding breakpoints, and examining the stack to find a method I didn't know was interfering with the animated object.