InkGolem
InkGolem

Reputation: 2762

How do I implement iOS 9's UICollectionView interactive movement features?

iOS 9 added the ability tap and hold to rearrange collection view cells with minimal effort. Enabling this capability in the trivial situation is straightforward. Simply implement one function on your UICollectionViewController.

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

If you want more documentation on that function see its definition in UICollectionViewDataSource.

This doesn't just work with a custom layout though. What does it take to make it work in a more complex case?

Upvotes: 1

Views: 550

Answers (1)

InkGolem
InkGolem

Reputation: 2762

It isn't well documented, but there are 2 mandatory overrides for this to work correctly. In your UICollectionViewLayout subclass implement the following 2 functions

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    return self.itemAttributes.filter { $0.frame.intersects(rect) }
}

First you need to make sure that the item attributes from your layout are filtered to only include the attributes in the given rect. If you include more, it gets confused.

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
    return self.itemAttributes.first(where: { $0.indexPath.item == indexPath.item })
}

Not sure why this is necessary, you'd think that UIKit could infer the correct attributes based on previous calls, but it can't. Anyway, you just need to be able to fetch the correct attributes for the given indexPath.

Upvotes: 1

Related Questions