Christian W
Christian W

Reputation: 383

Custom Data Not Working with itemProvider for Drag/Drop Collection View Functionality - Swift

I have a collection view that displays data arranged in a custom data model (struct) called "claimData."

claimData declaration:

struct claimData {
    var image = UIImage()
    var imageTitle = String()
    var hasCustomDescription = Bool()
    var customDescription = String()
    var isAnInitial = Bool()
    var isDamage = Bool()
    var isUnrelated = Bool()
    var isAnOption = Bool()
    var isACondition = Bool()
}

I share the state of this data via a sharedInstance because I am utilizing a floating panel.

class PageDataSource {
    var theData: ReviewDataController?
    static let sharedInstance = PageDataSource()
    private init() {}
}

ReviewDataController simply holds an array of claimData called "tableViewReviewData".

I'm trying to implement the Drag/Drop feature in my floating panel's collectionView, but I can't seem to get the itemProvider working with my custom data model.

This is what I have at the moment:

func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        let item = PageDataSource.sharedInstance.theData?.tableViewReviewData[indexPath.item]
        let itemProvider = NSItemProvider(object: item)
        let dragItem = UIDragItem(itemProvider: itemProvider)
        dragItem.localObject = item
        return [dragItem]
    }

This is the error I'm getting for the itemProvider: "Argument type 'claimData?' does not conform to expected type 'NSItemProviderWriting'"

Thanks for your help and let me know if you have any questions!!

Upvotes: 0

Views: 203

Answers (1)

Christian W
Christian W

Reputation: 383

I found another way to accomplish this same collection view cell re-order operation that works with custom data and isn't as hard to set up.

@objc func handleLongPressGesture(_ gesture: UILongPressGestureRecognizer) {
        guard let collectionView = myCollectionView else {
            return
        }
        
        switch gesture.state {
        case .began:
            guard let targetIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else {
                return
            }
            collectionView.beginInteractiveMovementForItem(at: targetIndexPath)
            
        case .changed:
            collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: collectionView))
        case .ended:
            collectionView.endInteractiveMovement()
            
        default:
            collectionView.cancelInteractiveMovement()
        }
        
    }
    
    func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        if let item = PageDataSource.sharedInstance.theData?.tableViewReviewData.remove(at: sourceIndexPath.row) {
            PageDataSource.sharedInstance.theData?.tableViewReviewData.insert(item, at: destinationIndexPath.row)
        } else {
            print("The item could NOT be moved!!!")
        }
    }

and in viewDidLoad simply add a long-press gesture recognizer, like such:

let gesture = UILongPressGestureRecognizer(target: self,
                                                   action: #selector((handleLongPressGesture(_:))))
        myCollectionView.addGestureRecognizer(gesture)

Upvotes: 1

Related Questions