Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIDropInteractionDelegate performDrop not called?

I am trying to build a simple test app to learn Drag and Drop APIs. For this question I am focusing only on the Drop scenario. I have a blank View Controller, with the safari app open (multitasking) I then try to drag an image from google onto the View Controller's view.

I can drag the image from safari to my app's View Controller, but when I let go, this call below is never called:

func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession)

This is my code:

class EditTestVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        view.addInteraction(UIDropInteraction(delegate: self))
    }

}

extension EditTestVC:UIDropInteractionDelegate {

    func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool { // 1
        print("canHandle session: \(session)")
        return true
//        return session.canLoadObjects(ofClass: UIImage.self)
    }

    func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal { // 2
        print("sessionDidUpdate session: \(session)")
        return UIDropProposal(operation: .copy)
    }

    func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
        print("performDrop session: \(session)")
    }


}

The top two methods are called, this one:

func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool

and this one:

func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal

So, I am trying to figure out why this one:

func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession)

is never called.

Any suggestion?

like image 512
zumzum Avatar asked Feb 21 '19 22:02

zumzum


2 Answers

In my case it was a programming error where I've written the following:

func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {

    return UIDropProposal(operation: .move)
}

But you cannot always use move! Only if session.allowsMoveOperation is true!

From the move documentation:

You may use this operation only if the drop session's allowsMoveOperation property is true; otherwise, it's treated as a UIDropOperation.cancel operation. [...]

From the cancel documentation:

If the user attempts a drop activity, the drag operation is canceled and the dropInteraction(_:performDrop:) delegate method is not called.

like image 115
Qbyte Avatar answered Oct 13 '22 16:10

Qbyte


first of all, as of iOS 15 dragSessionAllowsMoveOperation is true by default

Discussion If you don't implement this method, the default return value is YES.

In my case func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)

was not called because I had set a breakpoint inside

func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?)

This breakpoint was preventing, for same reason, the other delegate method to be triggered. As soon as I removed them everything worked fine.

I hope this help others as it was driving me crazy.

like image 28
Mat Avatar answered Oct 13 '22 16:10

Mat