如何使用自动布局在超级视图之间制作动画?

时间:2015-10-13 13:17:44

标签: ios autolayout

我有两个大视图,视图A和视图B.视图A包含一个子视图C,它有自动布局约束,将它定位在A的中心。我想动画C从A移动到B,这意味着从A中删除C,将其作为子项添加到B,并将约束定位在B的中心,然后使该移动在一秒钟内发生。

我遇到的问题是当我删除并添加视图及其约束时,移动立即发生:C从A的中心跳到B的中心。是否有一个简单的解决方案我失踪了吗?我现在的一系列事件是:

  • 启动动画块
  • c.removeFromSuperview()
  • b.addSubview(c)
  • b.addConstraints(...)

2 个答案:

答案 0 :(得分:1)

更改约束后,您可以设置布局过程的动画。

[UIView animateWithDuration:0.25
             animations:^{
                     [self.view layoutIfNeeded];
                 }];

如果您仍然看到跳跃,请尝试将点从当前Superview(其容器中视图的当前帧)转换为New Superview,将子视图添加到此翻译帧的新superview(如果需要,使用约束),然后更改约束适当的价值观(以及动画布局)

答案 1 :(得分:1)

如果您要添加额外的巨大视图D怎么办? D将涵盖(A和B)视图。你应该做点什么

  • 创建D
  • C.removeFromSuperview()
  • 使用约束将C添加到D,这些约束将C放在与A
  • 的中心相同的位置
  • 更改约束(C应移至B&#39的中心动画)
  • 从D中删除C并将其添加到B(更新C的约束)

像这样的东西

- (IBAction)MAGIC:(id)sender
{
    UIView* view = [[UIView alloc] initWithFrame:self.view.bounds];
    view.backgroundColor = [UIColor clearColor];
    [self.view addSubview:view];

    CGRect fromRect = [self.top convertRect:self.white.frame toView:view];

    [self.white removeFromSuperview];
    [view addSubview:self.white];
    NSLayoutConstraint* topConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(top)-[_white]"
                                                                               options:0
                                                                               metrics:@{@"top":@(CGRectGetMinY(fromRect))}
                                                                                 views:NSDictionaryOfVariableBindings(_white)].lastObject;
    NSLayoutConstraint* leftConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(left)-[_white]"
                                                                                 options:0
                                                                                 metrics:@{@"left":@(CGRectGetMinX(fromRect))}
                                                                                   views:NSDictionaryOfVariableBindings(_white)].lastObject;

    [view addConstraints:@[topConstraint, leftConstraint]];
    CGRect bottomViewFrameInView = [self.bottom convertRect:self.bottom.bounds toView:view];
    [view layoutIfNeeded];

    topConstraint.constant = CGRectGetMidY(bottomViewFrameInView) - CGRectGetHeight(self.white.bounds)/2;
    leftConstraint.constant = CGRectGetMidX(bottomViewFrameInView) - CGRectGetWidth(self.white.bounds)/2;

    [UIView animateWithDuration:0.5
                     animations:^{
                         [view layoutIfNeeded];
                     }
                     completion:^(BOOL finished) {
                         [self.white removeFromSuperview];
                         [self.bottom addSubview:self.white];
                         NSLayoutConstraint* topConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(top)-[_white]"
                                                                                                    options:0
                                                                                                    metrics:@{@"top":@(CGRectGetMidY(self.bottom.bounds) - CGRectGetHeight(self.white.bounds)/2)}
                                                                                                      views:NSDictionaryOfVariableBindings(_white)].lastObject;
                         NSLayoutConstraint* leftConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(left)-[_white]"
                                                                                                      options:0
                                                                                                      metrics:@{@"left":@(CGRectGetMidX(self.bottom.bounds) - CGRectGetWidth(self.white.bounds)/2)}
                                                                                                        views:NSDictionaryOfVariableBindings(_white)].lastObject;
                         [self.bottom addConstraints:@[topConstraint, leftConstraint]];
                         [view removeFromSuperview];
                     }];
}

enter image description here