ios - 将 NSLayoutConstraints 与 CALayer 支持的 View 结合使用无法正确设置动画

标签 ios animation calayer autolayout nslayoutconstraint

我有一个自动布局设置,带有一个改变 NSLayoutContraint 常量值的动画

// set the slide in view's initial height to zero
self.adViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self.adContainerView
                                                           attribute:NSLayoutAttributeHeight
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:nil
                                                           attribute:NSLayoutAttributeNotAnAttribute
                                                          multiplier:1.0
                                                            constant:0.0];
[self.view addConstraint:self.adViewHeightConstraint];

//  later, set the slid in view's height to non-zero
double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    self.adViewHeightConstraint.constant = 100;
    [UIView animateWithDuration:2.5 animations:^{
        [self.view layoutIfNeeded];
    }];
});

这正确地动画了我所拥有的 View 的大小,因此工作正常。然而,我看到的问题是,在 2.5 秒动画的持续时间内,我拥有的一些自定义图层支持 View 没有被重新绘制。

我看到的行为是自定义图层支持的 View 被要求在动画开始时绘制最终位置,然后应用一个转换在动画持续时间内拉伸(stretch) View ,直到它最终看起来正确.

enter image description here

这 4 个镜头显示的是红色条动画向上,然后两个蓝色 View 分别缩小高度以适应尺寸减小。该层知道如何为每个边界变化正确绘制自己,但动画并没有要求它在动画的每一步都重新绘制......只是在开始时。这就是为什么黑色圆圈看起来像椭圆形的原因——它与图像 #4 一样是两半,但被拉伸(stretch)了。

自定义 CAlayer 子类有一个重写的方法:drawInContext:,并且该层将 needsDisplayOnBoundsChange 设置为 YES.

因此,问题仍然存在......我如何告诉 NSLayoutConstraints 的动画在整个动画期间让 View 重绘?

最佳答案

这是一个已知问题(如果你用谷歌搜索它,你会看到一些不错的结果,尽管我认为这个答案虽然着重于不同的症状,但它是迄今为止我所见过的描述该问题的最清晰的答案UIView scaling during animation ...这是一个古老的答案,但我相信仍然适用)。

恕我直言,最简单的解决方案是将图层放在一个不随动画调整大小的 View 中(例如,一个固定大小的新 View ,其约束使其保持在您的内容 View 的中心,但不会改变大小与您的内容 View 一样)。这样,您就可以享受基于约束的动画,但不会丢失自定义图层的纵横比/大小。

关于ios - 将 NSLayoutConstraints 与 CALayer 支持的 View 结合使用无法正确设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17982834/

相关文章:

Android RotateAnimation 完成

ios - 如何停止 CATransform3DMakeScale 动画缩放变化?

ios - CALayer 的内容中心无法快速工作

ios - 带有透明孔的 CALayer

ios - Google Analytics 如何计算请求/点击频率?

ios - 将 NSFetchedResultController 的结果附加到数组 swift

ios - 如何以编程方式滚动和停止 UIScrollView?

ios - 自定义iOS导航 Controller 动画: is this wrong?

ios - 如何使用 REST API 从 Parse.com 下载文件?

ios - 在键入时获取 UITextField 中的整个文本的简单方法是什么?