无法将CollectionViewCell移动到最后

时间:2016-10-19 16:39:34

标签: ios swift uicollectionview uigesturerecognizer

我在UICollectionView中有一个UIViewController。我配置了一个手势识别器来移动单元格。它适用于将单元格移动到除结尾之外的任何索引。最令人沮丧的是,当我试图将一个单元移动到最后时,应用程序并没有崩溃 - 它只是挂起。我可以退出ReorderViewController并回到它。视图正常重新加载。

我从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()
}

任何想法:非常感谢我的错误。

1 个答案:

答案 0 :(得分:2)

我想我已经破解了它。关于CoreData问题的预感是一个红色的鲱鱼(就像我对它没有多少经验一样好!)。挂断是由处理程序方法开始时的guard语句引起的。具体来说,您的方法检查是否存在与手势位置相关的有效索引路径;如果手势移出集合视图,我认为所有事情都会混淆,因此你会在该点停止退出时(而不是崩溃)。然而,移动一些东西似乎解决了这个问题:

    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,它存储了一个有效索引路径可用的最后位置 - 这样,如果手势在集合视图之外结束,则该单元被发送到该索引路径。

无论如何,这有点粗糙,但肯定似乎可以防止挂起。希望有所帮助!