在iOS 11和Swift 4中拖放集合视图单元格

在本教程中,我们将说明如何在iPhone IOS 11中的同一屏幕上的两个集合视图中拖放集合视图单元格。在IOS 11中,苹果引入了两种协议类型UICollectionViewDragDelegate和UICollectionViewDropDelegate,通过使用这些协议方法,我们可以将一个集合视图单元格从一个集合视图拖放到另一个集合视图。

注意:-请注意, iPhoneiPad均支持拖放功能,在iPad上,不同应用程序,同一应用程序和同一屏幕之间可使用拖放功能,但在iPhone中,仅可在相似屏幕上使用拖放功能。

首先创建基础项目

通过使用CollectionViewDataSource和CollectionViewDelegate方法在同一屏幕上创建带有两个collectionView的基础项目。 您可以从此处下载基础项目。

现在,我们开始拖放代理,将CollectionViewCell从FirstCollectionView移至SecondCollectionView。

拖动集合视图单元格(UICollectionViewDragDelegateprotocol)

首先,我们需要实现拖动委托的itemsForBeginning方法,其中我们需要返回UIDragItem的数组。

注意:-必须记住将dragDelegate设置为self。 并启用dragInteraction。

override func viewDidLoad() { 
super.viewDidLoad()
topCollectionView?.dragDelegate = self
topCollectionView.dragInteractionEnabled = true
}

itemsForBeginning- >提供项目以开始与给定indexPath相关联的拖动。 如果返回一个空数组,则拖动会话将不会开始。
为了创建UIDragItem,首先我们需要创建NSItemProvider,并将该项目提供者传递到UIDragItem(itemProvider 🙂

 extension ViewController: UICollectionViewDragDelegate { 
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let dragItem = self.dragItem(forPhotoAt: indexPath)
return [dragItem]
}

/// Helper method
private func dragItem(forPhotoAt indexPath: IndexPath) -> UIDragItem {
let imageName = self.arrayFirst[indexPath.row]
let image = UIImage(named: imageName)
let itemProvider = NSItemProvider(object: imageName as NSItemProviderWriting)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = imageName
return dragItem
}
}

删除集合视图单元格(CollectionViewDropDelegate协议)

现在首先我们将要删除collectionViewCell的那个集合视图的CollectionViewDropDelegate设置为self。

 bottomCollectionView.dropDelegate = self 

实现用于处理放置项的放置会话的方法。 为此方法DropDelegate提供方法canHandle session: 如果我们不处理此方法,则默认情况下将返回“ YES”

 func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool { 
return session.canLoadObjects(ofClass: NSString.self)
}

现在实现这些方法以将项目拖放到collectionView中

 func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) { 
  let destinationIndexPath = coordinator.destinationIndexPath ?? IndexPath(item: 0, section: 0) 
loadAndInsertItems(at: destinationIndexPath, with: coordinator)
}

func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
}

private func loadAndInsertItems(at destinationIndexPath: IndexPath, with coordinator: UICollectionViewDropCoordinator) {
let destinationIndexPath: IndexPath

if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
} else {
let section = bottomCollectionView.numberOfSections - 1
let row = bottomCollectionView.numberOfItems(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
}

coordinator.session.loadObjects(ofClass: NSString.self) { items in
guard let string = items as? [String] else { return }

var indexPaths = [IndexPath]()

for (index, value) in string.enumerated() {
let indexPath = IndexPath(row: destinationIndexPath.row + index, section: destinationIndexPath.section)
self.arraySecond.insert(value, at: indexPath.row)
indexPaths.append(indexPath)
}
self.bottomCollectionView.insertItems(at: indexPaths)
}
}

在此处下载完整的项目。