iOS - UICollectionViewCell 内的 UIScrollView - 内部视图的动画不正确(延迟)

Posted

技术标签:

【中文标题】iOS - UICollectionViewCell 内的 UIScrollView - 内部视图的动画不正确(延迟)【英文标题】:iOS - UIScrollView inside UICollectionViewCell - animation is not correct (delayed) for inner view 【发布时间】:2017-07-07 17:09:28 【问题描述】:

我有这个层次结构:

UICollectionView - UICollectionViewCell - UIScrollView - UIView: DetailedView

在 UIView 中,我有详细的内容(按钮、图像视图等)。 UICollectionView 有高度限制。

在按钮点击内部,我有一个动画来平滑地改变高度:

UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveLinear, animations: 
           self.heightConstraint.constant = newHeight
           self.collectionViewLayout.invalidateLayout()


           self.superview?.layoutIfNeeded()
, completion:  finished in )

UICollectionView 的动画是正确的,但 DetailedView 的动画很奇怪。看起来项目被拉伸了,并且它们的大小被延迟校正。

如果我滚动到侧面,我在 UICollectionView 中有 4 个单元格。

如果我不调用self.collectionViewLayout.invalidateLayout(),内容(DetailedView)会在UICollectionView 内部重复,并且根本没有内容的动画。它只是“坐在”它的位置并重复。

(现在这些是我在一个视图中的 4 个单元格中的 2 个,但它们应该在各自的“页面”上)

但应该是的

我的场景有这些限制(我已经删除了启动动画的按钮,它没有限制并且被放在左上角):

Height Constraint 在动画内部发生变化。

【问题讨论】:

【参考方案1】:

您需要提供更多代码。但是首先要考虑两件事:

动画和.layoutIfNeeded() 是在应用程序的任何位置调用的密集方法。他们通常会完全重新计算约束、大小、定位等。您还需要记住,在您调用它的视图中出现的subviews 越多,任务就越繁重。在您的情况下,您在层次结构中的最低视图上调用它,然后向上移动到它们的superViews 再次调用它,然后在层次结构的最高视图上第三次调用它..

因此,您为每个子视图(在本例中为 DetailedView)执行了三次工作,为中间子视图(您的 scrollView)执行了两次,为包含您的 UICollectionView 的视图执行了一次。 所以只是假设,你在这里做了太多的布局调整,一直试图动画它,这可以解释为什么你的collectionView的动画很好(只计算一次),但是它的单元格的子视图不是(它们是多次重新计算,而不是与collectionView 的同时)

您需要弄清楚调整大小需要哪个视图,通常,您只需在特定视图上调用.layoutIfNeeded() 即可为您需要的任何内容设置动画。根据这个定义,当您重新调整许多子视图的大小时,您需要测试您的层次结构以找到调用.layoutIfNeeded() 的正确位置,这些子视图本身正在获得约束更改。虽然在层次结构中为更高级别的视图设置动画确实意味着您也重新计算所有子视图,但如果您在调用 @987654332 之前更改它们的约束,则 UIView 的动画方法也应该注意为它们消除过渡@。

不幸的是,随着您的层次结构变得越来越复杂,它确实变得越来越具有挑战性,因此反复试验有时是安全的方法。

其次,如果没有更多代码,几乎不可能判断您的方法是否适合您的用例。如果您在本身是 UIScrollView 子类的 collectionView 中添加滚动视图,情况尤其如此。因此,可能还有一些与您想要的动画相冲突的触摸交互/动画。否则我不会更正您的代码,因为我不知道您要做什么,但首先要弄清楚应该执行哪个视图.layoutIfNeeded()

现在,看看这些谷歌的视频,他们进入这个层次结构.layoutIfNeeded() 问题非常好:

Animating Constraints Part 1

Animating Constraints Part 2

【讨论】:

@murpguy 我添加了一些关于约束和行为的细节 看看你的约束,你有一个混合了topAnchor和bottomAnchor的高度约束,以及一个混合了前导和尾随Anchor的宽度约束。像以前一样,你为同一件事设置了两组约束。通常,应该使用前导+尾随,或者其中任何一个+宽度约束。所以尝试在这里删除一些约束(我通常会尽量避免宽度和高度约束,并坚持单元格内的容器视图的前导/顶部/底部/尾随)。同样对于您的代码,您可以粘贴用于调整大小的代码吗?

以上是关于iOS - UICollectionViewCell 内的 UIScrollView - 内部视图的动画不正确(延迟)的主要内容,如果未能解决你的问题,请参考以下文章

ios开发之-- tableview/collectionview获取当前点击的cell

UICollectionView

如何以编程方式创建 UICollectionViewCell

如何从 UICollectionViewCell 访问 UICollectionView 中 Cell 的 indexPath

Xcode 6 beta 4,UIButton 在collectionviewcell 中不负责

{python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO