Gesture Guide

Programming touches, clicks, swipes and other finger movements

Last update : June 2019

📘

Sourcecode

Please see the UgGestureDemo project for the source code created in this chapter here. See Installing examples for information on how to download the examples.

Introduction

This tutorial introduces gesture management, i.e listening to and capturing the different gestures on the device. The supported gestures with their class are listed below:

  • Tap gesture: One or multiple time click (i.e. doubleclick) of an element or page (SCDSvgTapGestureRecognizer)
  • Pan gesture : User moves finger over the screen in one continuous motion. The movement starts with a started event, followed by changed events and ends with an ended event (SCDSvgPanGestureRecognizer)
  • Swipe gesture : swipe in one of the following directions: Up, Down, Left and Right (SCDSvgSwipeGestureRecognizer)

All gestures use the native implementation of the underlying mobile OS.

Demo app structure

Our sample app is very simple. We added a nice background, a circle (custom control) where we added an id = "circle1" , a rectangle (custom control) where we added an id = "rect1" and a label. The label is bound to a variable of the page class using the binding editor.

Implementing gestures

You follow four steps to setup a gesture:

  • Step 1. Define the action. Create a function that is called when the gesture is executed
  • Step 2. Create the recognizer instance and pass the function as a reference
  • Step 3. (Optionally) Configure the recognizer
  • Step 4. Add the recognizer to the object that should react on the gesture

Here an example of implementing these steps

let report = "Page tapped"
		
  // Step 1 : implement the action as a function
  func onActionTap(recognizer:SCDSvgGestureRecognizer?) {
   let tapEvent = recognizer as! SCDSvgTapGestureRecognizer
   print(report + " \(tapEvent.numTaps) times") 
  }
		
  // Step 2 : Create recognizer
  let tapGestureRecognizer = SCDSvgTapGestureRecognizer(handler: onActionTap)
		
  // Step 3 : Configure recognizer. Set number of taps to wait for before triggering
  tapGestureRecognizer.numTaps = 1
		
  // Step 4 : Add recognizer to object
  self.page!.drawing!.gestureRecognizers.append(tapGestureRecognizer)

Implement the action

The action is implemented as a function. Within the function, you implement the desired behavior when the gesture occurs. The function parameter needs to be of type SCDSvgGestureRecognizer? and have no result / return void.

To access all gesture type specific attributes, you need to cast the generic SCDSvgGestureRecognizer recognizer into a gesture specific class

// Cast for Tap gesture
let tapEvent = recognizer as! SCDSvgTapGestureRecognizer

Create recognizer

Nothing special here.

Configure recognizer

The configuration depends on the type of gesture.

Add recognizer

You can add gestures to any control and graphical element (Button, Circle, Rectangle) using the gestureRecognizers property.

  • To add gestures to controls (Buttons, containers, pages), use .drawing.gestureRecognizers
  • to add gestures to use elements (SCDSvgRect/Circle/...), use .gestureRecognizers

All gestures are added in the load method of the main page:

// page adapter initialization
override func load(_ path: String) {		
  super.load(path)

  // setup gestures for entire page
  let tapGesture:SCDSvgTapGestureRecognizer = getTapGesture("tapped")
  let swipeGesture:SCDSvgSwipeGestureRecognizer = getSwipeGesture()

  self.page!.drawing!.gestureRecognizers.append(tapGesture)
  self.page!.drawing!.gestureRecognizers.append(swipeGesture)
  
  // setup gesture for the rectangle with id "rect1"only
  let tapGestureRect = getTapGesture("tapped rec")
  
  if let rect = self.page!.drawing!.find(byId: "rect1") as? SCDSvgRect {
	  rect.gestureRecognizers.append(tapGestureRect)
  }
  
  // setup and move circle using Pan gesture
  let panGesture:SCDSvgPanGestureRecognizer = getPanGesture()
  self.circle = self.page!.drawing!.find(byId: "circle1") as? SCDSvgCircle
	self.circle!.gestureRecognizers.append(panGesture)
 }

General Gesture behavior

The information about behavior of all gestures is stored in the SCDSvgGestureRecognizer class.

AttributeDescriptionComment
target:SCDSvgTouchReceiver The reference to the graphical object that you touched, for instance a circle, rectangle, button ..
state: SCDSvgTouchHandlerState (possible, began, changed, ended, failed)Information about the state of the finger (touched the screen, moving, ended) A began event is triggered when the finger touches the screen

A changed event is triggered when the user moves the finger

* A ended event is triggered when the finger was lifted

Tap gesture

The tap gesture is created using the SCDSvgTapGestureRecognizer class. It has property numTaps that define after how many tabs the tap gesture is to be triggered. So if you set numTaps=2, it will only fire after a double tap / doubleclick.

AttributeDescriptionComment
numTabs : IntConfiguration property. Defines after how many taps the gesture action is executed.Set to 2 for double tap.

Pan gesture

The pan gesture is created using the SCDSvgPanGestureRecognizer class. The pan gesture is used to track and react to movements along a path.

The Pan gesture provides you with the following PanGesture specific attributes.

AttributeDescriptionComment
locationThe current location of your finger on the screen in (x,y) coordinates.
startLocationThe location in (x,y) coordinates where the motion began, i.e. where you touched down with the finger.
deltaX, deltaYThe relative distance from the time the last movement was reported.Lets say you get to events e1 and e2. Using deltaX and deltaY of e2, you can tell by how much your finger has moved since your received the e1 event.

Here we use the delta information to move the circle

func getPanGesture() -> SCDSvgPanGestureRecognizer {
		
  // Create action
  func onPanAction(recognizer:SCDSvgGestureRecognizer?) {
			
   // cast generic gesture to pan gesture
   let panEvent = recognizer as! SCDSvgPanGestureRecognizer
			
   // lets change location of circle graphics object
   self.circle!.cx.value = self.circle!.cx.value + panEvent.deltaX
   self.circle!.cy.value = self.circle!.cy.value + panEvent.deltaY       
  }
		
  // create recognizer
  let panGestureRecognizer = SCDSvgPanGestureRecognizer(handler: onPanAction) 
		
  // Configure gesture --> nothing to configure. Return it
  return panGestureRecognizer
}

Swipe gesture

The swipe gesture allows you to capture a swipe in ONE specific direction. Create the gesture using SCDSvgSwipeGestureRecognizer and specify the direction that you want to capture using the direction attribute.

If you want to capture swipes in different directions, you need to create and add multiple recognizer.

AttributeDescriptionComment
direction : SCDSvgSwipeDirection (up, down, left, right)Contains the direction in which the swipe has occured
func getSwipeGesture() -> SCDSvgSwipeGestureRecognizer {
		
 // Use short cut form to create recognizer and specify action
 let swipeGestureRecognizer = SCDSvgSwipeGestureRecognizer { handler in
   self.setLabel(to:"Swiped to left")
 }
	
  // Configure: capture swifts from left to right only
  swipeGestureRecognizer.direction = .left 
	 
  return swipeGestureRecognizer
}

Capturing Up, down, moving ... events

Each gesture inherits certain attributes from its base class SCDSvgGestureRecognizer that can be used on all gesture types.

AttributeDescriptionComment
target: SCDSvgTouchReceiver?Identifies the graphical element that has been clicked
state: SCDSvgTouchHandlerState
(possible, began, changed, ended, failed)
Identifies the current state the gesture is in.For instance, pressing down on a visual element is causing an "began" event, while lifting the finger is causing an "ended" event

Up and down gesture

For instance, we want to know when a button has been clicked, change its background and set its background color back to default once the finger is lifted:

  • We need to check for the began and ended events
  • This events can be used to set the background color
func getUpDownGestureForButton() -> SCDSvgPanGestureRecognizer {

    // Create action*
    func onPanAction(recognizer:SCDSvgGestureRecognizer?) {
    		
        // depending on whether we are inside or outside of the button,
        // we set the button background a different color
        switch(recognizer!.state) {
          case .began:
            self.button1!.backgroundColor = self.colorPressedGreen
          case .ended: 
            self.button1!.backgroundColor = self.colorDefaultGreen
          default:
           return 
        }
    }
		
  // create recognizer
  let panGestureRecognizer = SCDSvgPanGestureRecognizer(handler: onPanAction) 
 	
  // Configure gesture --> nothing to configure. Return it
  return panGestureRecognizer
}

Conclusion

We hope this helps implementing all your needs. Any questions, feedback, let us know. We are happy to help.