UICollectionViewFlowLayout 中的动画更改
Animate changes in UICollectionViewFlowLayout
我正在使用 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 更改之后明显发生。
你的 collectionView(_:layout:sizeForItemAt:) 在我看来是正确的(我有类似的东西)。
您需要调用 performBatchUpdates(_:completion:) AFTER you make your changes and BEFORE you call
layoutIfNeeded`。
// 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)
会为您设置。
特别是,我所做的是:
self.myCollectionView.performBatchUpdates({
self.causeSomeOtherVisualChanges()
}, completion: { _ in
self.smyCollectionView.scrollToItem(at: index, at: .centeredHorizontally, animated: true)
})
我正在使用 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 更改之后明显发生。
你的 collectionView(_:layout:sizeForItemAt:) 在我看来是正确的(我有类似的东西)。
您需要调用 performBatchUpdates(_:completion:) AFTER you make your changes and BEFORE you call
layoutIfNeeded`。
// 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)
会为您设置。
特别是,我所做的是:
self.myCollectionView.performBatchUpdates({
self.causeSomeOtherVisualChanges()
}, completion: { _ in
self.smyCollectionView.scrollToItem(at: index, at: .centeredHorizontally, animated: true)
})