Reversible UIViewPropertyAnimator causes a problem with frame animations

I use UIViewPropertyAnimatorframes to animate UICollectionViewCell. I look at the speed of the gesture recognizer to decide if the animator should end naturally or go back and go back to its original state.

In all simulations, on my iPhone 5s, as well as 6s +, these animations work flawlessly. However, on my iPhone 7+, I get a weird falsification of the frame when I change the animation. See the code below how I do it. The effect on the iPhone 7+ is that as soon as I install reversed = YESand then call continueAnimationWithTimingParameters:durationFactor:, the frame immediately goes to a completely different part of the screen and then starts the reverse animation. Only after the animation has finished work does the frame go back to where it was supposed to go back.

I tried to remove the spring time parameters, but that did not affect.

This is an abstracted version of the code:

- (void)prepareAnimation {
    // Called when user begins panning in certain direction
    // ...
    self.cardFrameAnimator = [[UIViewPropertyAnimator alloc] initWithDuration:0.5 dampingRatio:0.8 animations:^{
        [self currentCell].frame = targetFrame;
    }];
}

- (void)panningEndedWithTranslation:(CGPoint)translation velocity:(CGPoint)velocity
{
    if (self.cardFrameAnimator.isRunning)
    {
        return;
    }

    CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
    CGVector velocityVector = CGVectorMake(velocity.x / 500, velocity.y / 500);

    __weak CardStackCollectionViewController *weakSelf = self;

    switch (self.currentState) {
        case CurrentStateStacked:
            if (translation.y <= -screenHeight / 3 || velocity.y <= -100)
            {
                // Let the animation run to completion
                self.cardFrameAnimator.reversed = NO;
                [self setCurrentCellsCornerRadius:0];
                [self.cardFrameAnimator addCompletion:^(UIViewAnimatingPosition finalPosition) {
                    weakSelf.activeCellState = CurrentStateFullscreen;
                }];
            }
            else
            {
                // Revert the animation back to the default state
                self.cardFrameAnimator.reversed = YES;
                [self setCurrentCellsCornerRadius:20];
                [self.cardFrameAnimator addCompletion:^(UIViewAnimatingPosition finalPosition) {
                    weakSelf.activeCellState = CurrentStateStacked;
                }];
            }
            break;
        case CurrentStateFullscreen:
            if (translation.y >= screenHeight / 3 || velocity.y >= 100)
            {
                // Let the animation run to completion
                self.cardFrameAnimator.reversed = NO;
                [self setCurrentCellsCornerRadius:20];
                [self.cardFrameAnimator addCompletion:^(UIViewAnimatingPosition finalPosition) {
                    weakSelf.activeCellState = CurrentStateStacked;
                }];
            }
            else
            {
                // Revert the animation back to the default state
                self.cardFrameAnimator.reversed = YES;
                [self setCurrentCellsCornerRadius:0];
                [self.cardFrameAnimator addCompletion:^(UIViewAnimatingPosition finalPosition) {
                    weakSelf.activeCellState = CurrentCellStateFullscreen;
                }];
            }
            break;
    }

    UISpringTimingParameters *springParameters = [[UISpringTimingParameters alloc] initWithDampingRatio:0.8 initialVelocity:velocityVector];
    [self.cardFrameAnimator continueAnimationWithTimingParameters:springParameters durationFactor:1.0];
}
+4
source share

Source: https://habr.com/ru/post/1676184/


All Articles