use-gesture icon indicating copy to clipboard operation
use-gesture copied to clipboard

On iOS drag stops working after press-and-hold gesture fired on it

Open dmagunov opened this issue 2 years ago • 6 comments

Describe the bug

On iOS drag stops working after press-and-hold gesture fired on it

Sandbox or Video

Sandbox: https://codesandbox.io/s/hidden-rain-1h4oc9

Video:

https://user-images.githubusercontent.com/3579475/178121049-2c886219-003d-4ae7-b29b-94a611e84db6.MP4

Information:

  • Use Gesture version: >= 10.1.6
  • Device: iPhone13 Pro Max
  • OS: iOS 15.5
  • Browser: Chrome

Checklist:

  • [X] I've read the documentation.
  • [X] If this is an issue with drag, I've tried setting touch-action: none to the draggable element.

dmagunov avatar Jul 09 '22 20:07 dmagunov

Any reason why the sandbox isn't using the latest version of the lib?

dbismut avatar Jul 11 '22 15:07 dbismut

I just cloned, an existing example, which is failing on the latest version

dmagunov avatar Jul 11 '22 15:07 dmagunov

That example pulls the latest version of the lib while the sandbox you link uses 10.1.6, hence me asking. In any case I'm able to reproduce with the latest version, thanks for posting the bug.

dbismut avatar Jul 11 '22 16:07 dbismut

Thanks, just to clarify, an example sandbox is failing on the latest version, that is why I downgraded the library

Screenshot 2022-07-11 at 18 26 17 Screenshot 2022-07-11 at 18 22 44

dmagunov avatar Jul 11 '22 16:07 dmagunov

It's not failing. Codesandbox is failing for some reason. Not sure what happens there but if you fork it and reload the page it works 🤷‍♂️

dbismut avatar Jul 11 '22 16:07 dbismut

FYI I got same issue on the latest version 10.3.0

OS: iOS 17.0.3 Browser: Chrome mobile


Temporary solution

After press-and-hold, Google context menu is opened. So gesture state is still dragging. I add an interval to cancel gesture if gesture state is still dragging greater than x seconds.

  const lastDrag = useRef<Record<string, any>>({})

  const bind = useDrag(
    ({
      args: [dragItemOrgIndex],
      active,
      movement: [, y],
      dragging,
      cancel,
    }) => {
      // do something

      // save current drag event
      lastDrag.current = {
        cancel,
        dragging,
        timeStamp: Date.now(),
      }
    }
  )

  useEffect(() => {
    const id = setInterval(() => {
      if (!lastDrag.current.dragging) {
        return
      }

      if (
        Date.now() - lastDrag.current.timeStamp > 5000 &&
        lastDrag.current.cancel
      ) {
        lastDrag.current.cancel()
      }
    }, 500)

    return () => {
      clearInterval(id)
    }
  }, [])

reallongnguyen avatar Oct 16 '23 19:10 reallongnguyen