Skip to content

JerryFans/DragAndDropKit

main
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 

DragAndDropKit

Version License Platform Language

iOS15下一行代码集成跨应用间拖拽传递数据(A Simple way help you drop or drag your source (like UIImage) between different App In iOS15+ Or iPad OS 11+.)

CocoaPods

pod 'DragAndDropKit', '0.2.0'

Drag Usage

UIView Drag Usage

最快只需两行代码即可实现拖拽,支持链式写法


/*
             你想拖拽时候给予的souce, 目前支持NetworkImageDropSource、NetworkVideoDropSource、ImageDropSource、VideoDropSource、TextDropSource五种
             */
            self.networkImageView.drag.dropSource = NetworkImageDropSource(imageUrl: "http://image.jerryfans.com/sample.jpg")
            
            //开启拖拽
            self.networkImageView.drag.enabled()

以及可选协议转链式闭包

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
            }

UICollectionView & UITableView Drag Usage

UICollectionView、UITableView因为实习的协议不同,但本质写法是差不多的。 两者enabled后都必须至少实现tableViewDidItemsForBeginning 或 collectionViewDidItemsForBeginning 闭包,返回相应的DragItem。DragItem封装的也是上面所说的5种DropSource。

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)
                ]
            }

collectionView,如果要实现一些生命周期方法,可以实现一下生命周期闭包,同样是链式语法。

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")
            }

Drop

从其他应用的接收data到到本应用(亲测支持系统相册、备忘录、QQ发送聊天等) DragAndDropKit本组件目前支持Drop 接收 UIImage、本地视频(路径下的视频)、网络图片、网络视频、文本等。目前也是支持UIView及其类UIImageView、UILabel等、以及TableView、CollectionView快速拖动其子Cell。

Usage

支持类型参数,所有UIView类别、TableView、CollectionView、均可赋值supportSources,用来声明drop接收时候能支持的类型数据,默认全部支持(Image、Video、Text)三种。(注:并不是系统api只支持这三种,是这三种比较广泛,第一期先支持此三种数据的接收)


c.drop.supportSources = [.rawImage,.rawVideo,.text]

UIView Drop, didReceivedDropSource闭包必须实现用以接收到source后你对source的处理,其他可选。


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("请移入右上角图片中替换"),
                         .withoutAnimation(true),
                         .position(.top),
                         .autoDismissDuration(.seconds(value: 3)),
                         .bgColor(UIColor.jf.rgb(0x000000, alpha: 0.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 }
                self.imageView.layer.borderWidth = 0.0
            }
        }

UICollectionView类似,也是collectionViewDidReceivedDropSource必须处理,其他生命周期闭包,可选。


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)
            }

UITableView类似,也是tableViewDidReceivedDropSource必须处理,其他生命周期闭包,可选。


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)
            }

效果:

拖拽本应用的data到其他实现了Drop协议的应用(亲测支持系统相册、备忘录、网页里面的文本选中范围后直接拖拽等) DragAndDropKit本组件目前支持拖拽UIImage、本地视频(路径下的视频)、网络图片、网络视频、文本等。目前支持UIView及其类UIImageView、UILabel等、以及TableView、CollectionView快速拖动其子Cell。

Author

fanjiaorng919, fanjiarong_haohao@163.com

License

DragAndDropKit is available under the MIT license. See the LICENSE file for more info.

About

A Simple way help you drop or drag your source (like UIImage) between different App.

Resources

License

Stars

Watchers

Forks

Packages

No packages published