I want to perform two simultaneous movement animations. First animation on firstView
starts immediately. Second animation on secondView
, starts after a slight delay while the first animation is still running. secondView
constraint is related to firstView
. The code works perfectly well on iOS 8.
firstView
and secondView
are subviews of view
view
|--- firstView
|--- secondView
Code:
UIView *firstView = ...;
UIView *secondView = ...;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:firstView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraint:constraint];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.5 delay:0.15 options:UIViewAnimationOptionCurveEaseInOut animations:^{
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:secondView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:firstView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraint:constraint];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
On iOS 7, once the second layoutIfNeeded
is called, the first animations stops and only the seconds animation animates.
Any suggestions?
Answering my own question.
I ended up doing the animation in a 2-step (3-step, depends how you count) solution. First add the constraints without calling layoutIfNeeded
. Then update the firtView
and secondView
frames. Lastly call layoutIfNeeded
in the completion block of the last animation.
Code:
UIView *firstView = ...;
UIView *secondView = ...;
/* first step */
NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:firstView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraint:constraint1];
NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:secondView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:firstView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraint:constraint2];
/* second step */
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
CGRect firstViewFrame = CGRectMake(...); // set frame according to constaint1
firstView.frame = firstViewFrame;
}];
[UIView animateWithDuration:0.5 delay:0.15 options:UIViewAnimationOptionCurveEaseInOut animations:^{
CGRect secondViewFrame = CGRectMake(...); // set frame according to constaint2
secondView.frame = secondViewFrame;
} completion:^(BOOL finished) {
/* second and a half step */
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];