iosobjective-cswiftnslayoutconstraintuiviewanimationtransition

How to animate constraints one by one in IOS?


I have 6 views. I want to animate the constraints one by one, ie, i need the animation on second view only after first, then after second the third and so on. I have added the code in the completion handler of the animations, but it is not working. initial value of all the constraint is set to 300 in storyboard. I want to change it to 0 one by one. Now, only the first animation is working. This is what i have done.

layoutTopFirst.constant = 0.0;
    [UIView animateWithDuration:1.0 animations:^{
        [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {
        self->layoutTopSecond.constant = 0.0;
        [UIView animateWithDuration:1.0 animations:^{
            [self.view layoutIfNeeded];
        } completion:^(BOOL finished) {
            self->layoutTopThird.constant = 0.0;
            [UIView animateWithDuration:1.0 animations:^{
                [self.view layoutIfNeeded];
            } completion:^(BOOL finished) {
                self->layoutTopFourth.constant = 0.0;
                [UIView animateWithDuration:1.0 animations:^{
                    [self.view layoutIfNeeded];
                } completion:^(BOOL finished) {
                    self->layoutTopFifth.constant = 0.0;
                    [UIView animateWithDuration:1.0 animations:^{
                        [self.view layoutIfNeeded];
                    } completion:^(BOOL finished) {
                        self->layoutTopSixth.constant = 0.0;
                        [UIView animateWithDuration:1.0 animations:^{
                            [self.view layoutIfNeeded];
                        } completion:^(BOOL finished) {
                            
                        }];
                    }];
                }];
            }];
        }];
    }];

How to do animations one after another?


Solution

  • If only the first one is animating, make sure that


    For what it's worth, you might consider eliminating your tower of completion handlers with keyframe animation, e.g.

    CGFloat relativeDuration = 1.0 / 6.0;
    
    [UIView animateKeyframesWithDuration:6 delay:0 options:kNilOptions animations:^{
        [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:relativeDuration animations:^{
            self.topConstraint1.constant = 0;
            [self.view layoutIfNeeded];
        }];
    
        [UIView addKeyframeWithRelativeStartTime:1.0 * relativeDuration relativeDuration:relativeDuration animations:^{
            self.topConstraint2.constant = 0;
            [self.view layoutIfNeeded];
        }];
    
        [UIView addKeyframeWithRelativeStartTime:2.0 * relativeDuration relativeDuration:relativeDuration animations:^{
            self.topConstraint3.constant = 0;
            [self.view layoutIfNeeded];
        }];
    
        [UIView addKeyframeWithRelativeStartTime:3.0 * relativeDuration relativeDuration:relativeDuration animations:^{
            self.topConstraint4.constant = 0;
            [self.view layoutIfNeeded];
        }];
    
        [UIView addKeyframeWithRelativeStartTime:4.0 * relativeDuration relativeDuration:relativeDuration animations:^{
            self.topConstraint5.constant = 0;
            [self.view layoutIfNeeded];
        }];
    
        [UIView addKeyframeWithRelativeStartTime:5.0 * relativeDuration relativeDuration:relativeDuration animations:^{
            self.topConstraint6.constant = 0;
            [self.view layoutIfNeeded];
        }];
    } completion:nil];
    

    Or, even simpler:

    NSArray <NSLayoutConstraint *> *constraints = @[self.topConstraint1, self.topConstraint2, self.topConstraint3, self.topConstraint4, self.topConstraint5, self.topConstraint6];
    
    CGFloat relativeDuration = 1.0 / (CGFloat) constraints.count;
    
    [UIView animateKeyframesWithDuration:totalDuration delay:0 options:kNilOptions animations:^{
        for (NSInteger i = 0; i < constraints.count; i++) {
            [UIView addKeyframeWithRelativeStartTime: ((CGFloat) i) * relativeDuration relativeDuration:relativeDuration animations:^{
                constraints[i].constant = 0;
                [self.view layoutIfNeeded];
            }];
        }
    } completion:nil];
    

    That yields:

    enter image description here