5 ms·
Using UIPanGestureRecognizer for gestures that should be recognized immediately on touch down is a common mistake I see a lot of people make. The problem is UIP
by lilyball 8y ago
Using UIPanGestureRecognizer for gestures that should be recognized immediately on touch down is a common mistake I see a lot of people make. The problem is UIPanGestureRecognizer doesn't actually start recognizing until the touch has moved a short distance, and at this point, you can't recover the original touch location, only the location at which the gesture recognizer began recognizing.
The solution is to use a UILongPressGestureRecognizer with minimumPressDuration set to 0. With this configuration, it will begin recognizing immediately on touch down, allowing you to take action even before the user has moved their finger (or pencil).
- yargg 8y agoHow do you track the translation during the gesture if you use UILongPressGestureRecognizer? Do you have an example you can link too?
- deleted 8y ago[deleted]
- eridius 8y agoAdmittedly you do lose the convenience methods from UIPanGestureRecognizer (sure would be nice if Apple would add them to UILongPressGestureRecognizer too), but you can recover translation just by grabbing the location of the recognizer in the associated view when the state moves to .began and then subtracting that from the current location on every subsequent .changed state callback. Calculating velocity is harder of course, but you could do it without too much difficulty by recording the previous location and timestamp and using that to calculate an instantaneous velocity (I'm not sure if this is what UIPanGestureRecognizer does or if it tries to smooth the velocity at all using multiple "frames"). I don't have any linkable examples offhand, but at a previous company one of our standard interview questions was to implement custom drag & drop of a view using a gesture recognizer, and our reference app used UILongPressGestureRecognizer because it let us do such nice things as visually "lift up" the view (scale it up slightly and add a drop shadow) the moment your finger touched it.
- dangwu 8y agoThat’s an incredibly specific interview question... there’s a lot more to iOS development than drag and drop. How has it fared for you?
- eridius 8y agoActually quite well. The fact that it's drag & drop is pretty irrelevant, except in that it's not something the interviewee has likely done before because it's not a very common thing to interrupt. What's more important is that it's fairly basic usage of UIGestureRecognizer (which is a common thing to need, at least if you're doing any kind of UI development) as well as some basic management of state involving 2 views (the view being dragged, and the destination view it's dropped into).
- eridius 8y agos/interrupt/implement/
- wingerlang 8y agoWhy not just use touchesBegan/touchesMoved directly?
- eridius 8y agoYou could do that, but it's more work than using a gesture recognizer, and doesn't compose as well (for example, with the gesture recognizer approach, you can easily add in other behavior like conditionally enabling a tap gesture recognizer that has higher priority than the drag gesture recognizer, without even having to touch the code that implements the drag beyond having access to its gesture recognizer object).
- wingerlang 8y agoUsing an instant LongPress seems like sort of a hack though. Interesting though, how do you transition from the instant LongPress into the "Pan" gesture? Or does the LongPress by itself also get the 'moved' events?
- eridius 8y agoThe UILongPressGestureRecognizer gets 'moved' events. It's a continuous recognizer.
- raydev 8y agoCouldn't you also subclass UIPGR and override `touchesBegan`, etc? Gesture recognizers will receive the touches before the parent view does, so you can just saved the position when touch starts on it, and let it pick up from there.