5
votes

I've tried a number of things and to post code at this point would likely be confusing, so let me start with the concept.

I need to somehow combine the operations of long press and touch drag into a single operation, something like LongPressThenDragGestureRecognizer. I'm trying to accomplish this on an MKMapView, so I can't just disable user interaction the entire time, because I want the pan and zoom functionality of the map.

To complicate things a bit, the initial item (an MKOverlay object) that the user long-presses on to recognize interaction will need to be removed and replaced with a new drawn object. At that point, the the code doesn't care about the object anymore, only where the finger is at any given point (I will redraw the dragged object as they move).

This is the workflow:

  1. User is presented an overlay on the map
  2. User touches and holds on the item to let the app know they want to drag it
  3. The app replaces the overlay with a drawn object and disables the map so that it doesn't start panning (rather than dragging).
  4. User drags finger, and object redraws as they move.
  5. User lifts finger to complete the drag
  6. App replaces the drawn object with a new map overlay
  7. App enables user interaction on the map to allow pan/zoom/annotation selection, etc.

I've tried a number of things so far, with little success. The best results I have so far is listed below. This was done using a UILongPressGestureRecognizer on the MKMapView objects (checking intersection with overlay), and then overriding touchesBegan for map touch drag.

  • Overlay is shown and user successfully performs a long-press gesture that gets recognized appropriately
  • Map user interaction is disabled and overlay is replaced with drawn object
  • User has to lift finger and touch down again to initiate the drag operation
  • When user lifts finger, new overlay is drawn and map interaction is enabled again

I'm so close, I just don't know how to combine the gestures into one, so that the user doesn't have to lift his/her finger and touch down again to start the drag.

Any ideas are greatly appreciated.

1
I have done this before in a simpler fashion but used long press to initiate dragging none the less. I did it with a simple bool. A long press set a bool to yes after 0.25 seconds and the dragging gesture was only allowed to return if the bool was yes.Ryan Poolos

1 Answers

0
votes

If it's a complex gesture like this, I would be tempted to avoid a gesture recognizer altogether and move to touchesBegan, touchesMoved, touchedEnded, touchesCancelled with some state that you move though as the gesture happens to know where you are.

MKMapView has a UIResponder base class so it should be easy to make your own derived version of MKMapView which responds to the touch events (remembering to passing them up to the super the map to maintain it's normal functionality).