作者:有情人都在外头_943 | 来源:互联网 | 2023-01-29 13:07
我正在尝试将Drag and Drop实现到我共享图像的应用程序中.
我的所有图像都是高性能缩略图(即小尺寸),因此我不能将它们用作我UIDragItem
的图像,至少不能用作最终图像.
我正在寻找的是一种方法,为我的原始图像提供URL并将其发送为UIDragItem
,然后使目标异步获取图像.当图像存储在iCloud中时,这在照片应用程序中完成,所以它必须以某种方式可能,我似乎无法弄清楚如何.
1> Chris..:
事实证明,该解决方案非常简单,并且在此WWDC期间的会话227 数据传输与拖放中进行了描述.
您基本上将要拖动的任何对象符合NSItemProviderWriting,然后实现两件事.
NSItemProviderWriting:
用于支持基于对象初始化项目提供程序的接口,在提供复制或拖动项目时由源应用程序使用.
第一步
实施writableTypeIdentifiersForItemProvider
,让您的接收器知道您提供什么类型的对象.这是一个具有降低保真度的类型标识符数组(他们在视频中很好地描述了这一点)
第二步
执行loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping (Data?, Error?) -> Void) -> Progress?
繁重的工作,当接收器尝试加载您提供的对象时,将调用它.
例
您可以忽略下面提取的数据的具体细节(我正在使用firebase),但使用本机URLSession API将以相同的方式工作.
extension Media: NSItemProviderWriting {
//Provide the types you want you are supplying
static var writableTypeIdentifiersForItemProvider: [String] {
return [(kUTTypeImage as String)]
}
func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping (Data?, Error?) -> Void) -> Progress? {
print("Item provider would like to write item from path: \(metadata.path!)")
guard let path = metadata.path else { return nil }
//Allow a maximum of ~30mb to be downloaded into memory if images, 1GB if video.
let maxSize:Int64 = (isVideo ? 1000 : 30) * 1024 * 1024
let storage = Storage.storage().reference(withPath: path)
let progress = Progress(totalUnitCount: 100)
var shouldCOntinue= true
//When the receiver cancels this block is called where we will set the `shouldContinue` to false to cancel the current task
progress.cancellatiOnHandler= {
shouldCOntinue= false
}
let task = storage.getData(maxSize: maxSize) { data, error in
//Once the data is fetched or we encounter an error, call the completion handler
completionHandler(data, error)
}
if !shouldContinue {
task.cancel()
}
task.observe(.progress) { snapshot in
if let p = snapshot.progress {
progress.completedUnitCount = Int64(p.fractionCompleted * 100)
}
}
task.observe(.success) { snapshot in
print(snapshot)
}
task.observe(.failure) { snapshot in
print(snapshot)
}
return progress
}
}
然后在我们的DragDelegate中:
@available(iOS 11, *)
extension GridViewDelegateDataSource: UICollectionViewDragDelegate {
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let mediaItem = media[indexPath.item]
//You can now instantiate an NSItemProvider directly from your object because it conforms to the `NSItemProviderWriting` protocol
let itemProvider = NSItemProvider(object: mediaItem)
let dragItem = UIDragItem(itemProvider: itemProvider)
return [dragItem]
}
}