重新排序 CollectionView 单元格 iOS 11
Posted
技术标签:
【中文标题】重新排序 CollectionView 单元格 iOS 11【英文标题】:Reordering CollectionView cells iOS 11 【发布时间】:2017-09-02 20:36:38 【问题描述】:我知道 ios 11 为 collectionview 带来了新的拖放功能,但我在使用它时遇到了一个完全不同的问题。所以我想我会尝试使用 IOS 9 (see this link) 中引入的旧方法。我的问题是,在 iOS 11 上,仅当切换两个单元格时,移除手指时的结束动画才会奇怪。你可以在这个clip看到问题。
几天来我一直在尝试解决这个问题,但没有运气。它在 iOS 10 上运行良好,但在 iOS 11 上运行良好。任何帮助将不胜感激。
额外信息:我正在使用带有长按手势的集合视图来启动重新排序手势,如第一个链接中所示。但是,在使用 uicollectionviewcontroller 时仍然会出现问题
这是长按手势的代码:
func handleLongGesture(gesture: UILongPressGestureRecognizer)
switch(gesture.state)
case .began:
guard let selectedIndexPath = self.collectionView.indexPathForItem(at: gesture.location(in: self.collectionView)) else
break
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))
case .ended:
// this part misbehaves on ios 11 when two cells are swapped
collectionView.performBatchUpdates(
self.collectionView.endInteractiveMovement()
)
default:
collectionView.cancelInteractiveMovement()
【问题讨论】:
请添加一些代码sn-ps来说明你的问题,让帮助你更容易。 我在水平的collectionview中遇到了完全相同的问题,但不是垂直的。你的是水平的吗? 这很奇怪……我的是垂直的 你解决过这个问题吗?我遇到了完全相同的问题。 更新:我在调用 endInteractiveMovement() 后无意中调用了 invalidateLayout()。 invalidateLayout() 给我造成了丑陋的动画故障。不调用 invalidateLayout() 似乎已经为我修复了它。 【参考方案1】:首先,您无需将collectionView.endInteractiveMovement()
放在performBatchUpdates
块内。但尽管如此,这个问题也让我很烦恼。 iOS 10 和 11 与 endInteractiveMovement
之间的差异没有多大意义。
对于我的问题,我在我的 collectionView 上方放置了一个假快照单元格,并在我运行手势状态更改和 updateInteractiveMovementTargetPosition
时隐藏了下面的内容。一旦手势状态为.ended
,我正在从超级视图中删除假单元格,然后执行endInteractiveMovement
。但是现在使用 iOS 11,我在上一个答案的 cmets 中遇到了与 @prolfe 相同的问题。由于有问题的单元的这种无法预料的重新加载,我得到了这个奇怪的闪光。
我最终采用的解决方案是延迟我的假细胞移除,这样它就可以“掩盖”闪光。
我的pushBackView
方法将假单元格动画化回放置位置,然后删除假单元格。然后我制定延迟:
case .ended:
fakeCellView?.pushBackView [weak self] in // 'suppress' cell animation
DispatchQueue.main.asyncAfter(deadline: .seconds(0.01), execute:
self?.fakeCellView?.removeFromSuperview()
)
self?.collectionView?.endInteractiveMovement()
希望这会有所帮助!
【讨论】:
所以您指望移动单元的重新加载会在 1/100 秒内发生,对吧?我觉得这不是一个保证的事情。聪明,但不是一个很好的解决方案。我仍在寻找可以在调用endInteractiveMovement()
之后最终确定项目失效和单元格重新加载完成的内容。【参考方案2】:
无需在 performBatchUpdates 块内执行self.collectionView.endInteractiveMovement()
。
【讨论】:
iOS 10 有必要避免在拖动过程中松开单元格的奇怪行为。我希望它在 iOS 11 中的功能类似,但事实并非如此。 iOS10我没试过,我正在做一个新的iOS11项目。如果它在两个操作系统中的行为不同,为什么不使用:if #available(iOS 11.0, *) /* iOS11 code */ else /* iOS10 code */
。我知道这很烦人,但 collectionViews 发生了一些变化..
是的,我也尝试过,最糟糕的是,无论是否调用 performBatchUpdates,iOS 11 的行为都出乎意料。自 iOS 11 正式发布以来,我一直无法检查它是否已得到纠正。
我也遇到了 iOS 11 和 endIntractiveMovement
功能的问题。似乎 CollectionView 正在重新加载移动后很快移动的单元格(异步)。所以对我来说,我看到了闪光。而且由于该单元格的延迟重新加载,此后我也无法进行任何其他collectionview操作。 #available
在这里并不真正适用,因为我发现 iOS 11 中没有一个好的替代方案。 ?以上是关于重新排序 CollectionView 单元格 iOS 11的主要内容,如果未能解决你的问题,请参考以下文章
如何在锁定其中一些单元格时重新排序 UICollectionView 单元格