代码之家  ›  专栏  ›  技术社区  ›  netshark1000

UICollectionViewDropDelegate:在删除图标上拖动单元格

  •  0
  • netshark1000  · 技术社区  · 6 年前

    我有一个collectionview,并支持ios11的拖放功能。其中一个要求是需要将单元格拖到视图底部的垃圾箱中才能移除。有没有另一种可能性,然后使用第二个collectionview持有删除symbol?

    很遗憾,UIView不能是UICollectionViewDropDelegate。

    1 回复  |  直到 6 年前
        1
  •  1
  •   netshark1000    6 年前

            import UIKit
    
        class DragDropViewController: UIViewController
        {
            private var items1 = [String]()
            //MARK: Outlets
            @IBOutlet weak var collectionView1: UICollectionView!
            @IBOutlet weak var collectionView2: UICollectionView!
            @IBOutlet weak var trashImage: UIImageView!
    
    
    
            private func createData(){
                for index in 1...130{
                    items1.append("\(index)")
                }
            }
    
            private func indexForIdentifier(identifier: String)->Int?{
                return items1.firstIndex(of: identifier)
            }
    
            //MARK: View Lifecycle Methods
            override func viewDidLoad()
            {
                super.viewDidLoad()
    
                createData()
                trashImage.alpha = 0
                trashImage.layer.cornerRadius = 30
    
                self.collectionView1.dragInteractionEnabled = true
                self.collectionView1.dragDelegate = self
                self.collectionView1.dropDelegate = self
                self.collectionView2.dropDelegate = self
            }
    
            //MARK: Private Methods
    
            /// This method moves a cell from source indexPath to destination indexPath within the same collection view. It works for only 1 item. If multiple items selected, no reordering happens.
            ///
            /// - Parameters:
            ///   - coordinator: coordinator obtained from performDropWith: UICollectionViewDropDelegate method
            ///   - destinationIndexPath: indexpath of the collection view where the user drops the element
            ///   - collectionView: collectionView in which reordering needs to be done.
            private func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView)
            {
                let items = coordinator.items
                if items.count == 1, let item = items.first, let sourceIndexPath = item.sourceIndexPath
                {
                    var dIndexPath = destinationIndexPath
                    if dIndexPath.row >= collectionView.numberOfItems(inSection: 0)
                    {
                        dIndexPath.row = collectionView.numberOfItems(inSection: 0) - 1
                    }
                    collectionView.performBatchUpdates({
    
    
                        self.items1.remove(at: sourceIndexPath.row)
                        self.items1.insert(item.dragItem.localObject as! String, at: dIndexPath.row)
    
                        collectionView.deleteItems(at: [sourceIndexPath])
                        collectionView.insertItems(at: [dIndexPath])
                    })
                    coordinator.drop(items.first!.dragItem, toItemAt: dIndexPath)
                }
            }
    
            /// This method copies a cell from source indexPath in 1st collection view to destination indexPath in 2nd collection view. It works for multiple items.
            ///
            /// - Parameters:
            ///   - coordinator: coordinator obtained from performDropWith: UICollectionViewDropDelegate method
            ///   - destinationIndexPath: indexpath of the collection view where the user drops the element
            ///   - collectionView: collectionView in which reordering needs to be done.
            private func removeItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView)
            {
                collectionView.performBatchUpdates({
    
                    for item in coordinator.items
                    {
                        guard let identifier = item.dragItem.localObject as? String else {
                            return
                        }
    
                        if let index = indexForIdentifier(identifier: identifier){
                            let indexPath = IndexPath(row: index, section: 0)
                            items1.remove(at: index)
                            collectionView1.deleteItems(at: [indexPath])
                        }
                    }
                })
            }
        }
    
        // MARK: - UICollectionViewDataSource Methods
        extension DragDropViewController : UICollectionViewDataSource
        {
            func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
            {
                return collectionView == self.collectionView1 ? self.items1.count : 0
            }
    
            func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
            {
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell1", for: indexPath) as! DragDropCollectionViewCell
    
                cell.customLabel.text = self.items1[indexPath.row].capitalized
    
                return cell
            }
        }
    
        // MARK: - UICollectionViewDragDelegate Methods
        extension DragDropViewController : UICollectionViewDragDelegate
        {
            func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem]
            {
                let item = self.items1[indexPath.row]
                let itemProvider = NSItemProvider(object: item as NSString)
                let dragItem = UIDragItem(itemProvider: itemProvider)
                dragItem.localObject = item
                return [dragItem]
            }
    
            func collectionView(_ collectionView: UICollectionView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem]
            {
                let item = self.items1[indexPath.row]
                let itemProvider = NSItemProvider(object: item as NSString)
                let dragItem = UIDragItem(itemProvider: itemProvider)
                dragItem.localObject = item
                return [dragItem]
            }
    
        }
    
        // MARK: - UICollectionViewDropDelegate Methods
        extension DragDropViewController : UICollectionViewDropDelegate
        {
            func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool
            {
                return session.canLoadObjects(ofClass: NSString.self)
            }
    
            func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal
            {
                if collectionView === self.collectionView1
                {
                    return collectionView.hasActiveDrag ?
                        UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath) :
                        UICollectionViewDropProposal(operation: .forbidden)
                }
                else
                {
                    if collectionView.hasActiveDrag{
                        return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
                    }
    
    
                    for item in session.items
                    {
                        guard let identifier = item.localObject as? String else {
                            return UICollectionViewDropProposal(operation: .forbidden)
                        }
    //not every cell is allowed to be deleted
                        if Int(identifier)! % 3 == 0{
                            return UICollectionViewDropProposal(operation: .forbidden)
                        }
                    }
    
                    trashImage.backgroundColor = UIColor.red.withAlphaComponent(0.4)
                    return  UICollectionViewDropProposal(operation: .move, intent: .unspecified)
                }
            }
    
            func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)
            {
                let destinationIndexPath: IndexPath
                if let indexPath = coordinator.destinationIndexPath
                {
                    destinationIndexPath = indexPath
                }
                else
                {
                    // Get last index path of table view.
                    let section = collectionView.numberOfSections - 1
                    let row = collectionView.numberOfItems(inSection: section)
                    destinationIndexPath = IndexPath(row: row, section: section)
                }
    
                if coordinator.proposal.operation == .move{
                    if coordinator.proposal.intent == .insertAtDestinationIndexPath{
                        self.reorderItems(coordinator: coordinator, destinationIndexPath:destinationIndexPath, collectionView: collectionView)
                    }
                    else{
    
                        self.removeItems(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
                    }
                }
            }
    
            func collectionView(_ collectionView: UICollectionView, dropSessionDidExit session: UIDropSession) {
                 trashImage.backgroundColor = UIColor.clear
            }
    
            func collectionView(_ collectionView: UICollectionView, dropSessionDidEnd session: UIDropSession) {
                 trashImage.backgroundColor = UIColor.clear
            }
        }