3

我想同时执行两个运动动画。第一个动画firstView立即开始。第二个动画 on secondView,在第一个动画仍在运行时稍有延迟后开始。secondView约束与firstView. 该代码在 iOS 8 上运行良好。

firstView并且secondViewview

view  
    |--- firstView  
    |--- secondView    

代码:

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) {
}];

在 iOS 7 上,一旦第二个layoutIfNeeded被调用,第一个动画就会停止,只有第二个动画会动画。

有什么建议么?

4

2 回答 2

2

回答我自己的问题。

我最终以 2 步(3 步,取决于你如何计算)解决方案来制作动画。首先添加约束而不调用layoutIfNeeded. 然后更新firtViewsecondView框架。最后调用layoutIfNeeded最后一个动画的完成块。

代码:

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];
}];
于 2015-08-02T06:06:13.027 回答
0

两个重要说明

  1. 您需要在动画块中调用 layoutIfNeeded。苹果实际上建议你在动画块之前调用一次,以确保所有待处理的布局操作都已完成。
  2. 您需要在父视图(例如 self.view)上专门调用它,而不是在附加了约束的子视图上调用它。这样做将更新所有受约束的视图,包括为可能被约束到您更改约束的视图的其他视图设置动画(例如,视图 B 附加到视图 A 的底部,而您刚刚更改了视图 A 的顶部偏移量并且您想要视图 B用它制作动画)。

你必须这样做:

[self.view layoutIfNeeded];

NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:firstView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraint:constraint];

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
    [self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
于 2015-02-17T10:12:20.083 回答