UICollectionView, how to prevent one cell from being moved

Viewed 4820

I recently study collection view. I need to let some cells fix in their own index path, which mean they should not be exchanged by others and not be dragged. I now can use *- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath )indexPath to prevent them from dragging. I cannot prevent them from being exchanged by other cells.

Any one meet same issue?

Thanks

4 Answers
func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
    if proposedIndexPath.row == data.count {
        return IndexPath(row: proposedIndexPath.row - 1, section: proposedIndexPath.section)
    } else {
        return proposedIndexPath
    }
}

I found that when I used iOS 11+ drag and drop, targetIndexPathForMoveFromItemAt wouldn't get called. Implementing this method forbids the item from being dropped where I don't want it:

func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
    // disallow dragging across sections
    guard let sourcePath = session.items.first?.localObject as? IndexPath,
        let destPath = destinationIndexPath,
        sourcePath.section == destPath.section
        else {
            return UICollectionViewDropProposal(operation: .forbidden)
    }
    return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}

Note that I stored the source index path in localObject when the drag started, because I couldn't find a way to get this information otherwise.

In this example you can't move the first and last component of your array in your CollectionView You can use porposedIndexPath, this is for UiCollectionView delegate

Swift 3

   func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
                if proposedIndexPath.row == 0 ||   proposedIndexPath.row == yourArray.count - 1{
                    return IndexPath(row: 1, section: 0)
                }
                return proposedIndexPath
            }
Related