拖动时防止移动UICollectionViewCell的中心

thi*_*ryb 1 uicollectionview uicollectionviewcell ios9

我可以通过使用手势识别器拖动它来重新排序iOS 9上的UICollectionViewCells,并简化新的iOS 9支持以进行重新排序.

public func beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath) -> Bool // returns NO if reordering was prevented from beginning - otherwise YES
public func updateInteractiveMovementTargetPosition(targetPosition: CGPoint)
public func endInteractiveMovement()
public func cancelInteractiveMovement()
Run Code Online (Sandbox Code Playgroud)

我注意到当我开始拖动一个单元格时,它的中心变为触摸位置,我不喜欢这样.

如果我愿意的话,我希望能够将我的细胞拖到它的角落.

你知道怎么做吗?

非常感谢.

Spe*_*tis 7

(用Swift 3.1编写)

对于函数的targetPosition参数updateInteractiveMovementTargetPosition,而不是直接使用手势识别器的位置...

var location = recognizer.location(in: collectionView)            
collectionView.updateInteractiveMovementTargetPosition(location)
Run Code Online (Sandbox Code Playgroud)

...我创建了一个函数,它将单元格的中心拖动(collectionView updateInteractiveMovementTargetPosition 使用的位置,然后获取手势识别器在单元格中的触摸位置,并从单元格的中心减去该位置.

func offsetOfTouchFrom(recognizer: UIGestureRecognizer, inCell cell: UICollectionViewCell) -> CGPoint {

    let locationOfTouchInCell = recognizer.location(in: cell)

    let cellCenterX = cell.frame.width / 2
    let cellCenterY = cell.frame.height / 2

    let cellCenter = CGPoint(x: cellCenterX, y: cellCenterY)

    var offSetPoint = CGPoint.zero

    offSetPoint.y = cellCenter.y - locationOfTouchInCell.y
    offSetPoint.x = cellCenter.x - locationOfTouchInCell.x

    return offSetPoint

}
Run Code Online (Sandbox Code Playgroud)

我的var offsetForCollectionViewCellBeingMoved: CGPoint = .zero视图控制器中有一个简单的存储偏移量,因此每次手势识别器的位置发生变化时都不需要调用上面的函数.

所以我的手势识别器的目标看起来像这样:

func collectionViewLongPressGestureRecognizerWasTriggered(recognizer: UILongPressGestureRecognizer) {

    guard let indexPath = collectionView.indexPathForItem(at: recognizer.location(in: self.collectionView)),
        let cell = collectionView.cellForItem(at: indexPath), indexPath.item != 0 else { return }

    switch recognizer.state {

    case .began:

        collectionView.beginInteractiveMovementForItem(at: indexPath)

        // This is the class variable I mentioned above
        offsetForCollectionViewCellBeingMoved = offsetOfTouchFrom(recognizer: recognizer, inCell: cell)

        // This is the vanilla location of the touch that alone would make the cell's center snap to your touch location
        var location = recognizer.location(in: collectionView)

        /* These two lines add the offset calculated a couple lines up to 
        the normal location to make it so you can drag from any part of the 
        cell and have it stay where your finger is. */

        location.x += offsetForCollectionViewCellBeingMoved.x
        location.y += offsetForCollectionViewCellBeingMoved.y

        collectionView.updateInteractiveMovementTargetPosition(location)

    case .changed:

        var location = recognizer.location(in: collectionView)

        location.x += offsetForCollectionViewCellBeingMoved.x
        location.y += offsetForCollectionViewCellBeingMoved.y

        collectionView.updateInteractiveMovementTargetPosition(location)

    case .ended:
        collectionView.endInteractiveMovement()

    default:
        collectionView.cancelInteractiveMovement()
    }
}
Run Code Online (Sandbox Code Playgroud)