当前位置: 首页 > 知识库问答 >
问题:

将NSLayoutConstraints与CALayer支持的视图相结合无法正确设置动画

吉栋
2023-03-14

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

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

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

我看到的行为是,要求自定义图层背景视图在动画开始时绘制最终位置,然后应用变换,在动画持续时间内拉伸视图,直到最终看起来正确为止。

这4张照片显示的是红色条动画,然后两个蓝色视图的高度都在缩小,以适应尺寸的缩小。该层知道如何在每次边界更改时正确绘制自身,但动画不会要求它在动画的每一步都重新绘制。。。仅在开始时。这就是为什么黑色圆圈看起来像一个椭圆形-它与图#4的两半相同,但被拉伸了。

自定义的CAlayer子类有一个覆盖的方法:draInContext:,并且该层将需求量DisplayOnBoundsChange设置为YES

因此,问题仍然是。。。我如何告诉这个动画,让视图在整个动画过程中重画?

共有1个答案

仲孙疏珂
2023-03-14

这是一个已知的问题(如果你在谷歌上搜索它,你会看到一些很好的点击率,尽管我认为这个答案,尽管我承认它关注不同的症状,但它是迄今为止我看到的描述动画中UIView缩放问题的最清晰的答案……这是一个古老的答案,但我相信仍然适用)。

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

 类似资料:
  • 我有一个布局,即MotionLayout,它必须为我定义了motionscene约束集开始和结束的FrameLayouts。并且它们是正确的动画。 然后,在这个动画框架布局下,我添加了两个文本视图,在单击时,我尝试隐藏一个,显示另一个,但两个都保持可见 重写有趣的onViewCreated(View:View,SavedInstanceState:Bundle?){super.onviewcrea

  • 问题内容: 我正在安装我的系统(Windows 7 Pro 64位,通过Anaconda使用Python 3.5),以通过selenium使用Firefox,以遵循《 用Python测试驱动开发 》一书 。即使我将系统路径设置为指向geckodriver的文件夹(并重新启动了3次),Python仍然会引发错误。 如果我将python / selenium指向的确切位置,则会出现以下错误 在这一点上

  • 我正在学习这本Spring Security指南,我已经读到了“创建一个不安全的web应用程序”一节。在该节末尾,声明如下: 此时,您可以直接使应用程序可执行并运行应用程序,而无需登录任何内容。 创建基本的简单web应用程序后,您可以为其添加安全性。 我试图按照“使应用程序可执行”中描述的步骤,创建应用程序的不安全版本。但是,这些视图没有得到正确处理 例如,如果我导航到我得到了这个错误: 我发现这

  • 设置ARN所需的细节,得到一个设置给帧查看器的视频流。然后尝试将Kinesis视频流与Rekognition集成。

  • 我试图通过视图约束循环。 我在view1中添加了:顶部、尾部、前导和高度约束。 顶部、尾部和前导是主ViewControllers视图。 如果循环查看view1的约束,则只会看到高度约束。 NSLayoutConstraint:0x618000968A0 UIView:0x7fae6b409dd0。高度==146(激活) 所以我循环了它的superviews约束(ViewControllers主视

  • 所以我有一个包含两个片段、一个存储库和一个ViewModel类的活动,因为我遵循Android开发人员的指南来使用MVVM结构。到目前为止,它似乎是有效的,但我不确定在实现方面是否遵循了良好的实践。到目前为止,它看起来是这样的: 存储库类: ViewModel类: 显示图书列表的回收器视图: 片段1 问题: 1) 我用对了吗?我应该在onActivityCreated()或其他地方使用viewMo