嵌入容器视图时,UICollectionViewController重新排序不起作用

时间:2016-02-03 00:51:01

标签: ios swift uicollectionview ios9

当我将其添加到我的<activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <activity android:name="com.package.name.MapsActivity" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 子类

时,重新排序在iOS9中有效
UICollectionViewController

当此override func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) 子类嵌入容器视图中时,它不起作用。

我已经对问题进行了演示here

关于为什么或如何修复它的任何想法?

3 个答案:

答案 0 :(得分:15)

这里的问题是你将UICollectionView放在一个驻留在UIViewController中的UIContainerView中。这需要更多步骤才能使UICollectionView按预期工作。

将以下内容添加到CollectionViewController中的ViewDidLoad:

    self.collectionView!.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: "handleLongGesture:"))

然后将以下函数添加到CollectionViewController:

    func handleLongGesture(gesture: UILongPressGestureRecognizer)
    {

    switch(gesture.state)
    {

    case UIGestureRecognizerState.Began:
        guard let selectedIndexPath = self.collectionView!.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else
        {
            break
        }
        collectionView!.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
    case UIGestureRecognizerState.Changed:
        collectionView!.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
    case UIGestureRecognizerState.Ended:
        collectionView!.endInteractiveMovement()
    default:
        collectionView!.cancelInteractiveMovement()
    }
}

最后,请确保包含以下内容以确保正确处理dataSource:

    override func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath,toIndexPath destinationIndexPath: NSIndexPath) {
    // Swap the values of the source and destination
}

有关详情,请查看此link

希望这能帮到你。

答案 1 :(得分:15)

Scooter的回答是正确的! 这是Swift 3语法版本:

UIViewController

请注意,此代码不考虑触摸位置偏移量 - 因此您的手机将会“跳转”。当你开始拖动时,在你的手指下居中。如果您想阻止这种情况,那么您需要在CGPoint initialGestureLocationInCell属性中定义(在下面的代码中命名为[...] case .began: guard let selectedIndexPath = self.uiCollectionView.indexPathForItem(at: gesture.location(in: self.uiCollectionView)) else { break } let selectedCell = self.uiCollectionView.cellForItem(at: selectedIndexPath)! let gestureLocationInCell_RelativeToOrigin = gesture.location(in: selectedCell) let gestureLocationInCell_RelativeToCentre = CGPoint(x: gestureLocationInCell_RelativeToOrigin.x - selectedCell.frame.size.width/2, y: gestureLocationInCell_RelativeToOrigin.y - selectedCell.frame.size.height/2) self.initialGestureLocationInCell = gestureLocationInCell_RelativeToCentre self.uiCollectionView.beginInteractiveMovementForItem(at: selectedIndexPath) case .changed: let gestureLocationInCollectionView = gesture.location(in: gesture.view!) let targetPosition = CGPoint(x: gestureLocationInCollectionView.x - self.initialGestureLocationInCell.x, y: gestureLocationInCollectionView.y - self.initialGestureLocationInCell.y) self.uiCollectionView.updateInteractiveMovementTargetPosition(targetPosition) [...] )。然后用最初的例子代替:

{{1}}

答案 2 :(得分:0)

当嵌入到容器视图中时,UICollectionViewController不会安装它的重新排序手势识别器,因为installsStandardGestureForInteractiveMovement设置为false。目前尚不清楚这是故意还是错误。

一种解决方法:

对于嵌入式UICollectionViewController,在viewDidAppear中(或生命周期的更高版本)将installsStandardGestureForInteractiveMovement设置为true:

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.installsStandardGestureForInteractiveMovement = true
    }

重新排序将与非嵌入式UICollectionViewController相同。数据源只需要声明

func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)

请注意,您需要将collectionView的clipsToBounds设置为false,以便在将其拖到集合视图之外时能够看到单元格。但是,这意味着滚动到范围外的单元格也将可见,这可能取决于您的设计。