UICollectionViewFlowLayout 中的动画更改

Posted

技术标签:

【中文标题】UICollectionViewFlowLayout 中的动画更改【英文标题】:Animate changes in UICollectionViewFlowLayout 【发布时间】:2016-12-09 17:55:13 【问题描述】:

我正在使用UICollectionViewFlowLayout 在水平滚动视图中排列视图图块。默认情况下,我使用UICollectionViewDelegateFlowLayout 将它们设为正方形:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    var nominalSize = CGSize(width: collectionView.frame.height, height: collectionView.frame.height)
    return nominalSize

这样我得到方形瓷砖,大小与collectionView 的电流大小一致。但是,有一种情况是我修改了某些图块的标称尺寸,所以它看起来有点像:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    var nominalSize = CGSize(width: collectionView.frame.height, height: collectionView.frame.height)
    if someTest(indexPath) 
        nominalSize = self.tweakNominalSize(nominalSize)
    
    return nominalSize

我还没有想出的是如何触发集合视图 A)调用委托以重新布局和 B)如何使其更改动画。

我尝试过的:

1)

self.myCollectionView.setNeedsLayout()
UIView.animateWithDuration(200.milliseconds) 
    self.myCollectionView.layoutIfNeeded()

这没有任何作用。委托回调中的print() 语句表明它从未被调用过。

2)

self.schedulesView.setCollectionViewLayout(
    self.schedulesView.collectionViewLayout,
    animated: true)

这也无济于事。我不确定它是聪明还是什么。也许注意到它们是相同的并选择退出是足够聪明的?

3)

self.schedulesView.startInteractiveTransition(
    to: self.schedulesView.collectionViewLayout,
    completion: nil)
self.schedulesView.finishInteractiveTransition()

这确实会导致布局发生!但根本没有动画。它只是突然改变。它似乎将磁贴的右侧保持在原来的位置,而不是左侧,并且它似乎在我在两次调用之间进行了其他 UI 更改之后明显发生。

【问题讨论】:

performBatchUpdates(_:completion:)? 想把它写成答案吗?或者我会,如果你不这样做。 :) 【参考方案1】:

您的 collectionView(_:layout:sizeForItemAt:) 在我看来是正确的(我有类似的东西)。

您需要致电performBatchUpdates(_:completion:) AFTER you make your changes and BEFORE you calllayoutIfNeeded`。

// Some call that makes your call to `someTest()` in `collectionView(_:layout:sizeForItemAt:)` return what you want
myCollectionView.performBatchUpdates(nil, completion: nil)
myCollectionView.layoutIfNeeded()

不必调用myCollectionView.setNeedsLayout(),因为performBatchUpdates(_,completion) 会为您设置。

【讨论】:

似乎不需要layoutIfNeeded() 有趣...如果我不调用它,我正在做的事情根本不起作用。集合视图布局变化很奇怪。【参考方案2】:

具体来说,我所做的是:

self.myCollectionView.performBatchUpdates( 
    self.causeSomeOtherVisualChanges()
, completion:  _ in
    self.smyCollectionView.scrollToItem(at: index, at: .centeredHorizontally, animated: true)
)

【讨论】:

以上是关于UICollectionViewFlowLayout 中的动画更改的主要内容,如果未能解决你的问题,请参考以下文章