我在 UIViewController
中有一个 UICollectionView
。我配置了一个手势识别器来移动单元格。它适用于将单元格移动到除末尾以外的任何索引。最令人恼火的是,当我尝试将单元格移动到末尾时,应用程序不会崩溃——它只是挂起。我可以退出 ReorderViewController
并返回它。 View 会正常重新加载。
我从 viewDidLoad
调用这个方法来配置手势识别器:
func configureGestureRecognizer() {
// configure longPressGestureRecognizer
longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ReorderViewController.handleLongPressGesture))
longPressGesture.minimumPressDuration = 0.5
longPressGesture.delegate = self
self.collectionView.addGestureRecognizer(longPressGesture)
}
当 UILongPressGestureRecognizer
被触发时,它的处理程序被调用:
func handleLongPressGesture(gesture: UILongPressGestureRecognizer) {
guard let selectedIndexPath = self.collectionView.indexPathForItem(at: gesture.location(in: self.collectionView)) else {
return
}
let selectedCell = collectionView.cellForItem(at: selectedIndexPath)
switch gesture.state {
case .began:
print("began")
editMode = true
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
selectedCell?.isSelected = true
case .changed:
editMode = true
selectedCell?.isSelected = true
print("changed")
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: self.collectionView))
case .ended:
print("ended")
editMode = false
selectedCell?.isSelected = false
collectionView.endInteractiveMovement()
default:
print("default")
editMode = false
selectedCell?.isSelected = false
collectionView.cancelInteractiveMovement()
}
}
我可以毫无困难地使用手势移动单元格,只要我不将一个单元格移动到末尾即可。最烦人的是,应用程序不会崩溃——它只是挂起。我可以按 NavBar 上的“后退”按钮并转到之前的 ViewController 而不会崩溃并返回到 ReorderViewController。
这是我移动单元格的代码:
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let stuffToReorder = currentRoutine?.myOrderedSet.mutableCopy() as! NSMutableOrderedSet
stuffToReorder.exchangeObject(at: sourceIndexPath.row, withObjectAt: destinationIndexPath.row)
currentRoutine?.myOrderedSet = stuffToReorder as NSOrderedSet
appDelegate.saveContext()
}
非常感谢任何关于我的错误的想法。
最佳答案
我想我已经破解了它。我对 CoreData 问题的直觉是转移注意力(这也是我对它没有太多经验的原因!)。挂断是由处理程序方法开头的 guard 语句引起的。具体来说,您的方法检查是否存在与手势位置相关的有效索引路径;如果手势移出 Collection View ,我认为一切都会变得困惑,因此您会挂起(而不是崩溃),因为函数会在该点继续退出。然而,稍作调整似乎可以解决问题:
func handleLongPressGesture(gesture: UILongPressGestureRecognizer) {
guard let _ = collectionVC.collectionView else { return }
switch gesture.state {
case .began:
guard let selectedIndexPath = collectionVC.collectionView!.indexPathForItem(at: gesture.location(in: collectionVC.collectionView)) else { return }
selectedCell = collectionVC.collectionView!.cellForItem(at: selectedIndexPath)
print("began")
lastGoodLocation = gesture.location(in: collectionVC.collectionView!)
collectionVC.collectionView!.beginInteractiveMovementForItem(at: selectedIndexPath)
selectedCell.isSelected = true
case .changed:
selectedCell?.isSelected = true
if collectionVC.collectionView!.frame.contains(gesture.location(in: view)) {
print(gesture.location(in: view))
print(collectionVC.collectionView!.frame)
print("INSIDE COLLECTION VIEW!")
collectionVC.collectionView!.updateInteractiveMovementTargetPosition(gesture.location(in: collectionVC.collectionView!))
lastGoodLocation = gesture.location(in: collectionVC.collectionView!)
}
else
{
print("OUTSIDE COLLECTION VIEW!")
collectionVC.collectionView!.updateInteractiveMovementTargetPosition(lastGoodLocation) // Not sure this is needed
}
print("changed")
case .ended:
print("ended")
selectedCell?.isSelected = false
collectionVC.collectionView!.endInteractiveMovement()
default:
print("default")
selectedCell?.isSelected = false
collectionVC.collectionView!.cancelInteractiveMovement()
}
}
以这种方式实现,我将 selectedCell 的 guard 语句移到了 switch 的 .began 案例中,因为这是它唯一被初始化的地方。因此,我必须将 selectedCell 声明为类属性,以便稍后在其他情况下可以引用它。我还引入了一个 CGPoint 变量 lastGoodLocation,它存储有效索引路径可用的最后一个位置 - 这样,如果手势在 Collection View 之外结束,单元格将发送到该索引路径。
无论如何,这有点粗糙,但肯定可以防止挂起。希望对您有所帮助!
关于ios - 无法将 CollectionViewCell 移动到末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40137103/