【问题标题】:Reordering CollectionView cells iOS 11重新排序 CollectionView 单元格 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() 似乎已经为我修复了它。

标签: ios objective-c swift ios11


【解决方案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 中没有一个好的替代方案。 ?
猜你喜欢
  • 2016-12-19
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多