Skip to content

UICollectionViewで良い感じの並び替え方法

UICollectionViewで並び順の入れ替えをしたい場合、Drag and Dropの処理を使用すると、簡単に良い感じに実装できます。(iOS11以上)

初期設定

ViewDidLoad内などで、Drag and Dropを使えるように初期設定をします。

collectionViewのdragDelegateとdropDelegateを追加し、dragInteractionEnabledをtrueに設定します。

collectionView.dropDelegate = self
collectionView.dragDelegate = self
collectionView.dragInteractionEnabled

UICollectionViewDragDelegate

UICollectionViewDragDelegateのitemsForBeginningを実装します。

extension ViewController: UICollectionViewDragDelegate {
    func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        let itemIdentifier = indexPath.item.description
        let itemProvider = NSItemProvider(object: itemIdentifier as NSItemProviderWriting)
        let dragItem = UIDragItem(itemProvider: itemProvider)
        return [dragItem]
    }
}

UICollectionViewDropDelegate

UICollectionViewDropDelegateのdropSessionDidUpdate、performDropWithを実装します。

extension MemoViewController: UICollectionViewDropDelegate {
    func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
        return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
    }
}
func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) {
    if coordinator.proposal.operation == .move {
            guard let item = coordinator.items.first,
                  let destinationIndexPath = coordinator.destinationIndexPath,
                  let sourceIndexPath = item.sourceIndexPath else {
                return
            }

            collectionView.performBatchUpdates({
                // データソースの更新
                let n = dataList.remove(at: sourceIndexPath.item)
                dataList.insert(n, at: destinationIndexPath.item)
                //セルの移動
                collectionView.deleteItems(at: [sourceIndexPath])
                collectionView.insertItems(at: [destinationIndexPath])
            })
            coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)
    }
}

Apple ドキュメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です