Nerrolken
Nerrolken

Reputation: 1995

Detect user dragging items out of UICollectionView?

I've got a UICollectionView, and I'd like to be able to touch-and-drag items up and out of the View, and thus delete them. (Very much along the same lines as how the Dock works on OS X: drag something off and let go, and it is removed).

I've done some research, but almost everything I find is looking for CollectionViews that are drag-and-drop to reorder. I don't need to reorder (I'm happy to just remove the item at the given index from the source array and then reload), I just need to detect when an item is moved outside of the View and released.

So I suppose my questions are these:

1) Is that possible with the built-in CollectionView, some kind of itemWasDraggedOutsideViewFromIndex: method or something?

2) If not, is it something that can be done with a subclass (and specifically is it possible for a CollectionView beginner)?

3) Are there any code samples or tutorials you can recommend that do this?

Upvotes: 1

Views: 5313

Answers (3)

TDesign
TDesign

Reputation: 597

Yes there is.

1 - Conform your view to UIDropInteractionDelegate.

2 - Then add this line to your viewload or init:

For viewcontroller add to ViewDidload:

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

Or, for UIViews add to init:

self.addInteraction(UIDropInteraction(delegate: self))

3 - Then get the location for item being dragged here and have fun with it:

func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
    print(session.location(in: self))
    return UIDropProposal(operation: .move)
}

Upvotes: 1

sf13579
sf13579

Reputation: 355

Here is a helper class that I've been working on that does just that: implementation: https://github.com/Ice3SteveFortune/i3-dragndrop, hope it helps. There's examples on how to use it in the TestApp.

UPDATE

About a year on, this is now a full-on drag-and-drop framework. Hope this proves useful: https://github.com/ice3-software/between-kit

Upvotes: 3

RegularExpression
RegularExpression

Reputation: 3541

  1. There is no built-in method like you're suggesting. What you're wanting to be can be done but you'll have to handle it with a gesture recognizer and appropriate code to handle the drag/drop operation.

  2. I tried using a subclass to do this and finally went back to putting it in my view controller. In my case, though, I was dragging stuff in/out of the collection view as well as two other views on the screen.

  3. I don't know if you have the book, but the most helpful thing I found was Erica Sadun's Core iOS6 Develper's Cookbook, which has excellent code on drag/drop within Collection Views. I don't think it specifically addresses dragging outside of the CV, but for me the solution was to put the gesture recognizer on the common superview and always use its coordinates rather than the subview's coordinates.

One problem I hit was I wanted to be able to select cells with a tap as well as drag, and there is no way (despite Apple's docs to the contrary) to require the single tap gesture to fail on the collection view. As a result, I ended up having to use the long press gesture to perform the entire operation, and there is no translationInView for long press (there is locationInView) so that required some additional work:

iOS - Gesture Recognizer translationInView

Another thing that will make it harder or easier is the number of possible drop targets you have. I had many, in many different types of views (straight UIView, collectionview, and scrollViews). I found it necessary to maintain a list of "drop targets" and to test for intersections with targets as the dragged object was moved. Somehow, you have to be able to determine whether the view you're intersecting is a place where a drop can occur.

If you are addressing the specific situation of dragging something out of a view to delete it (like dragging to a trash can view) and that's it, this should not be complicated. You have to remember that when you do a transform your frame becomes meaningless, but the center is still good; so you end up using the center for everything that you would normally use the frame for.

Here is the closest thing I found online that was helpful; I didn't end up using this class though as I thought it would be too complicated to implement in my app.

http://www.ancientprogramming.com/2012/04/05/drag-and-drop-between-multiple-uiviews-in-ios/

Hope this has been some help.

Upvotes: 3

Related Questions