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.
Attribute | Description | Comment |
---|---|---|
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.
Attribute | Description | Comment |
---|---|---|
numTabs : Int | Configuration 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.
Attribute | Description | Comment |
---|---|---|
location | The current location of your finger on the screen in (x,y) coordinates. | |
startLocation | The location in (x,y) coordinates where the motion began, i.e. where you touched down with the finger. | |
deltaX, deltaY | The 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.
Attribute | Description | Comment |
---|---|---|
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.
Attribute | Description | Comment |
---|---|---|
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.
Updated over 5 years ago