小编典典

如何为约束更改设置动画?

all

我正在用一个更新旧的应用程序,AdBannerView当没有广告时,它会滑出屏幕。当有广告时,它会在屏幕上滑动。基本的东西。

旧样式,我将帧设置在动画块中。新样式,我有一个IBOutlet确定Y位置的自动布局约束,在这种情况下它是与超级视图底部的距离,并修改常量:

- (void)moveBannerOffScreen {
    [UIView animateWithDuration:5 animations:^{
        _addBannerDistanceFromBottomConstraint.constant = -32;
    }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    [UIView animateWithDuration:5 animations:^{
        _addBannerDistanceFromBottomConstraint.constant = 0;
    }];
    bannerIsVisible = TRUE;
}

横幅移动,完全符合预期,但 没有 动画。


更新: 我重新观看了涵盖动画的WWDC 12 演讲“掌握自动布局的最佳实践”
它讨论了如何使用
CoreAnimation 更新约束:

我尝试使用以下代码,但得到完全相同的结果:

- (void)moveBannerOffScreen {
    _addBannerDistanceFromBottomConstraint.constant = -32;
    [UIView animateWithDuration:2 animations:^{
        [self.view setNeedsLayout];
    }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    _addBannerDistanceFromBottomConstraint.constant = 0;
    [UIView animateWithDuration:2 animations:^{
        [self.view setNeedsLayout];
    }];
    bannerIsVisible = TRUE;
}

附带说明一下,我已经检查了很多次,这是在 线程上执行的。


阅读 304

收藏
2022-02-28

共1个答案

小编典典

两个重要说明:

  1. 您需要layoutIfNeeded在动画块内调用。苹果实际上建议你在动画块之前调用一次,以确保所有待处理的布局操作都已完成

  2. 您需要在 父视图 (例如self.view)上专门调用它,而不是在附加了约束的子视图上调用它。这样做将更新 所有 受约束的视图,包括为可能被约束到您更改约束的视图的其他视图设置动画(例如,视图 B 附加到视图 A 的底部,而您刚刚更改了视图 A 的顶部偏移量并且您想要视图 B用它制作动画)

尝试这个:

Objective-C

- (void)moveBannerOffScreen {
    [self.view layoutIfNeeded];

    [UIView animateWithDuration:5
        animations:^{
            self._addBannerDistanceFromBottomConstraint.constant = -32;
            [self.view layoutIfNeeded]; // Called on parent view
        }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen { 
    [self.view layoutIfNeeded];

    [UIView animateWithDuration:5
        animations:^{
            self._addBannerDistanceFromBottomConstraint.constant = 0;
            [self.view layoutIfNeeded]; // Called on parent view
        }];
    bannerIsVisible = TRUE;
}

斯威夫特 3

UIView.animate(withDuration: 5) {
    self._addBannerDistanceFromBottomConstraint.constant = 0
    self.view.layoutIfNeeded()
}
2022-02-28