Skip to content

The Two-Finger Tap: Undo Gesture for iOS Apps

The only built-in gesture for undo on iOS at the moment is to shake the device. This is not very intuitive to me and I’ve certainly done it by accident many times. The makers of Procreate chose a two-finger tap and have found that their users adapted to it nicely. This gesture is being adopted by more and more iOS developers. Here’s all the code you need to implement the two-finger tap for undo in your Xojo iOS apps.

An Example in Xojo

If you haven’t worked with gestures in Xojo, it’s really not that difficult. To demonstrate, I’ve created a simple iOS app that draws a circle wherever you tap.

The basic idea is that every time the user taps with a single finger, the tap information (tap as iOSEventInfo in the code below) is added to an array called TapHistory and the Canvas is forced to repaint. In the Canvas’ Paint event, it loops through the TapHistory array and draws a circle at each location:

For Each tap As iOSEventInfo In TapHistory
 Dim d, x, y As Integer
 d = 50 'the diameter of the circle to draw

 'get the X, Y position of the tap
 x = tap.PointerPosition(0).X
 y = tap.PointerPosition(0).Y

 'Draw the circle centered on the tap
 g.FillOval(x - d/2, y - d/2, d, d)
Next

To create the TapHistory array to keep track of all the taps, you use the Canvas control’s PointerDown event which fires anytime a tap occurs. The eventInfo as iOSEventInfo parameter tells you everything you need to know about a tap. In addition to the location, it tells you how many fingers were used. In this event, the example code determines if one or two fingers were used. If a single finger was used, the eventInfo is added to the TapHistory array to be used for drawing the circles. If two fingers are used, the user wants to undo so that last entry in the TapHistory array is removed.

Select Case eventInfo.PointerCount

 Case 1 'Tap with 1 finger
 'Add the tap to the list of taps
 TapHistory.Append(eventInfo)

 Case 2 'Tap with 2 fingers
 'Remove the last 1 Finger Tap as long as there
 'are any circles on the screen

 If TapHistory.Ubound > -1 Then
  TapHistory.Remove(TapHistory.Ubound)
 End If
End Select

'Repaint the canvas
Canvas1.Invalidate

Either way, the Canvas is invalidated which forces it to repaint thus looping through the TapHistory array and redrawing circles at all the remaining tap locations.

The Two Tap Undo Example is available if you’d like to play around with it.