preface
Some time ago, apple just released the official version of iOS15, and I upgraded my experience at the first time. Experience a very interesting interaction during the following video.
As shown in the video, iOS15 apple system album support pictures, videos, text and other direct drag copy to other applications (currently pro test with a memo, Tencent QQ is supported). As an iOS engineer, I was immediately interested in this. I consulted the official documents to find the implementation scheme. Based on the official Api, I designed DragAndDropKit, which was written by Swift, came with Drop and Drag namespaces, and supported chain syntax. In principle, two lines of code should allow your project to support dragging and sharing resources to other applications.
Support version
In principle, iPad OS 11 + is supported, and iPhone iOS15+ is supported.
Reference documentation
drag and drop
Download address
cocoaPods:
Pod 'DragAndDropKit', '0.1.0 from'Copy the code
github:
Github.com/JerryFans/D…
DragAndDropKit demo and usage
Drag
DragAndDropKit This component currently supports dragging and dropping UIImage, local video (video in the path), network image, network video, and text. UIView and its classes UIImageView, UILabel, TableView, CollectionView, etc.
UIView Drag Usage
Drag and drop can be implemented as soon as two lines of code, supporting chain writing
/* When you want to drag souce, Currently, NetworkImageDropSource, NetworkVideoDropSource, ImageDropSource, VideoDropSource, and TextDropSource are supported self.networkImageView.drag.dropSource = NetworkImageDropSource(imageUrl: "Http://image.jerryfans.com/sample.jpg") / / open drag self.net workImageView. Drag. Enabled ()Copy the code
And optional protocol chain closures
self.networkImageView.drag.enabled().didEndSession { interaction, session, operation in
}.didMoveSession { interaction, session in
}.didPreviewForDragSession { interaction, item, session in
return
}.didAllowsMoveOperationSession { interaction, session in
return false
}
Copy the code
UICollectionView & UITableView Drag Usage
UICollectionView, UITableView because the internship protocol is different, but the essence of writing is similar.
After both enabled must achieve at least tableViewDidItemsForBeginning or collectionViewDidItemsForBeginning closures, returned to the corresponding DragItem. DragItem encapsulates the same five dropSources described above.
tableView
tableView.drag.enabled().tableViewDidItemsForBeginning { [weak self] tableView, session, indexPath in
guard let self = self else { return [] }
//if you are the custom model, you should convert to DropSource Object (Text,Image or Video Drop Source)
let source = self.models[indexPath.row]
let itemProvider = NSItemProvider(object: source)
return [
UIDragItem(itemProvider: itemProvider)
]
}
Copy the code
CollectionView, if you want to implement some lifecycle methods, you can implement a lifecycle closure, again, chain syntax.
collectionView.drag.enabled() .collectionViewDidItemsForBeginning { [weak self] collectionView, session, indexPath in return self? .dragAndDropVM.dragItems(for: indexPath) ?? [] }.collectionViewWillBeginDragSession { collectionView, session in JFPopup.toast(hit: "collection view will begin drag") }.collectionViewDidEndDragSession { collectionView, session in JFPopup.toast(hit: "collection view did end drag") }Copy the code
|
Drop
DragAndDropKit This component supports Drop to receive UIImage, local video (video in path), network image, network video, text, etc. It also supports UIView and its classes UIImageView, UILabel, TableView, CollectionView, etc.
Usage
Support type parameters. All UIView categories, TableView, CollectionView, and supportSources can be assigned to declare the types of data that can be supported by DROP. By default, all three types of data (Image, Video, and Text) are supported. (Note: the system API does not only support these three kinds of data, but these three kinds of data are more extensive. The first phase will support the receipt of these three kinds of data.)
c.drop.supportSources = [.rawImage,.rawVideo,.text]
Copy the code
UIView Drop, didReceivedDropSource closures must be implemented to handle the source after you receive it, optionally.
self.view.drop.supportSources = [.rawImage] self.view.drop.enabled().didReceivedDropSource { [weak self] dropSources in for (_, item) in dropSources.enumerated() { if let imageSource = item as? ImageDropSource { self? .imageView.image = imageSource.image self? . ImageView. Layer. BorderWidth = 0.0 break}}}. DidEnterDropSession {interaction, Session in if session.localDragSession == nil {jfPopupview.popup.toast {[. Hit (" Please replace in image in upper right corner "), .withoutAnimation(true), .position(.top), .autoDismissDuration(.seconds(value: 3)), .bgColor(UIColor.jf.rgb(0x000000, alpha: 3))]}}}. DidUpdateDropSource {[weak self] interaction, session in guard let self = self else { return UIDropProposal(operation: UIDropOperation.cancel) } let dropLocation = session.location(in: self.view) let operation: UIDropOperation if self.imageView.frame.contains(dropLocation) { operation = session.localDragSession == nil ? .copy : .move self.checkIsMatch(match: true) } else { operation = .cancel self.checkIsMatch(match: false) } self.updateLayers(forDropLocation: dropLocation) return UIDropProposal(operation: operation) }.didEndDropSession { [weak self] interaction, session in guard let self = self else { return } let dropLocation = session.location(in: self.view) self.updateLayers(forDropLocation: dropLocation) self.checkIsMatch(match: false) }.didExitDropSession { [weak self] interaction, Session in guard let self = self else {return} the self. The imageView. Layer. BorderWidth = 0.0}}Copy the code
UICollectionView similar, is also collectionViewDidReceivedDropSource must deal with, other life cycle closures, optional.
c.drop.supportSources = [.rawImage,.rawVideo,.text]
c.drop.enabled().collectionViewDidReceivedDropSource { [weak self] collectionView, coordinator, dropSources in
let destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
} else {
let item = collectionView.numberOfItems(inSection: 0)
destinationIndexPath = IndexPath(item: item, section: 0)
}
var indexPaths = [IndexPath]()
for (index, item) in dropSources.enumerated() {
let indexPath = IndexPath(item: destinationIndexPath.item + index, section: destinationIndexPath.section)
self?.dragAndDropVM.addItem(item, at: indexPath.item)
indexPaths.append(indexPath)
}
self?.collectionView.insertItems(at: indexPaths)
}
Copy the code
UITableView similar, is also tableViewDidReceivedDropSource must deal with, other life cycle closures, optional.
t.drop.supportSources = [.rawImage,.rawVideo,.text]
t.drop.enabled().tableViewDidReceivedDropSource { [weak self] tableView, coordinator, dropSources in
guard let self = self else { return }
let destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
} else {
let item = tableView.numberOfRows(inSection: 0)
destinationIndexPath = IndexPath(row: item, section: 0)
}
var indexPaths = [IndexPath]()
for (index, item) in dropSources.enumerated() {
let indexPath = IndexPath(row: destinationIndexPath.item + index, section: destinationIndexPath.section)
self.models.insert(item, at: indexPath.row)
indexPaths.append(indexPath)
}
tableView.insertRows(at: indexPaths, with: .bottom)
}
Copy the code
Effect:
Subsequent support
-
TableView & collectionView supports multi-select drag and drop like system albums (currently only one cell can be dragged)
-
More DropSource support