使用自动布局约束在 UIScrollView 内为 UIView 设置动画

Posted

技术标签:

【中文标题】使用自动布局约束在 UIScrollView 内为 UIView 设置动画【英文标题】:Animating UIView inside of a UIScrollView with autolayout constraints 【发布时间】:2015-09-22 08:04:08 【问题描述】:

我有一个 UIScrollView 放置在一个 ViewController 内,我已经给了 AutoLayout Constraints 并且所有这些都满意。 scrollView 包含大约 20 个 UIButton 子视图。我也给了他们自动布局约束,他们也都很满意。

我需要做的是在视图首次启动时为这些按钮设置动画。这是我的动画代码

    for (UIButton *button in [scrollView subviews]) 
    CGRect mainFrame = [button frame];
    [UIView animateWithDuration:0.0 animations:^
        button.frame = CGRectMake(button.center.x, button.center.y, 0, 0);
     completion:^(BOOL finished) 
        [UIView animateWithDuration:1 delay:0.5 usingSpringWithDamping:0.3 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^
            button.frame = mainFrame;
         completion:^(BOOL finished) 
        ];
    ];


当我使用这段代码时,子视图没有动画。 但是当我设置

[button setTranslatesAutoresizingMaskIntoConstraints:YES];

它有效。但是这次我得到了错误 Unable to Simultaneously Satisfy constraints。

有没有其他方法可以做到这一点,还是我应该忽略错误消息并继续执行?

【问题讨论】:

【参考方案1】:

使用自动布局时不要修改框架。

你应该修改约束来实现动画并在动画块中调用[yourView layoutIfNeeded]

它通过设置setTranslatesAutoresizingMaskIntoConstraints 起作用,因为设置框架会导致创建约束。这些最终与您已经存在的约束冲突并导致约束警告。

或者,您可以使用视图的 transform 属性并为其设置动画以达到您想要的效果,因为我认为您只想要演示动画之类的东西。然后,您不必修改约束。 你会做这样的事情:

[UIView animateWithDuration:1.0 animations:^
  button.transform = CGAffineTransformMakeTranslation(10.0, 10.0);
];

【讨论】:

谢谢。有效。你能解释一下为什么转换有效吗? 我不知道实现细节,但我认为变换是直接应用于图层的,这是在约束确定视图的位置及其图层之后发生的。在布局过程中约束之后应用它的事实允许您在不影响约束的情况下修改位置。【参考方案2】:

您应该为约束中的常量值而不是每个按钮的框架设置动画。为您要设置动画的每个约束创建内部属性,然后使用UIViewanimateWithDuration。例如:

self.myConstraint.constant = 10;
[button setNeedsUpdateConstraints];
[UIView animateWithDuration:1 animations:^
  [button layoutIfNeeded];
];

【讨论】:

以上是关于使用自动布局约束在 UIScrollView 内为 UIView 设置动画的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 不使用自动布局约束

UIScrollView 不能使用自动布局和动态约束滚动

UIScrollView 不滚动 w/ 编程自动布局约束

uiscrollview的自动布局,视图层次结构没有为约束做好准备

UIView 不遵守 UIScrollView 中的自动布局约束

尽管添加了自动布局约束,但 UIScrollView 不滚动