Let's go by parts!
I'm trying to implement Drag and Drop
in my UICollectionViewController
.
The datasource for the UICollectionView
is an array
of a custom Model Struct
I've created.
As required I have set my collectionView.dragDelegate = self
and by doing so I've implemented the required protocol function
itemsForBeginning session: UIDragSession...
Here's where my problem starts:
struct Model {
// some variables
// Some initializations
}
var myModelDatasource: [Model] = [model1, model2, model3, ...] // it's a simple case example
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let item = myModelDatasource[indexPath.row]
let itemProvider = NSItemProvider(object: item)
let dragItem = UIDragItem(itemProvider: itemProvider) // <-- ERROR HERE, Even If i force cast as NSItemProviderWriting
dragItem.localObject = item
return [dragItem]
}
I cannot create a dragItem
because of my model doesn't conform to type NSItemProviderWriting
.
If I force a datasource to be of type String
and cast the item to NSString
it works, but not with my struct Model
.
Does anyone know how to resolve this issue?
You should use a class
(not a struct) for your Model
, because as you suggested you have to be conform to NSItemProviderWriting
(which inherits from NSObjectProtocol
):
The protocol you implement on a class to allow an item provider to retrieve data from an instance of the class.
Many APIs expect subclasses of NSObject
, hence you have to use a class,
Apple blog: struct vs class
So your Model
should be something like:
class Model : NSObject, NSItemProviderWriting {
public static var writableTypeIdentifiersForItemProvider: [String] {
return [] // something here
}
public func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping (Data?, Error?) -> Swift.Void) -> Progress? {
return nil // something here
}
}