The APIs on this page will only work with SDK 4.9+.
Low-level touch-gesture recognizers for building fully custom touch interactions on touch-capable hardware.
A recognizer watches the raw touch stream for one gesture — a tap, a pan (single-axis drag) or a swipe — and calls a RecognizerEventCb as the gesture progresses. Create one with a per-gesture constructor (tap_recognizer_create, pan_recognizer_create, swipe_recognizer_create), attach it to a Window, and read the current gesture data from the event callback. Recognizers are the building block for a custom scroll or drag.
For an ordinary scrollable list you do not need recognizers at all: on touch hardware MenuLayer already scrolls by touch. Reach for recognizers to build an interaction the built-in list does not give you — a custom menu, a drag, or acting on a raw tap or swipe. Note that a bare ScrollLayer does not scroll by touch on its own; you drive it with a pan recognizer, as below.
A ScrollLayer holds your own content but does not scroll by touch by itself. Attach a vertical pan recognizer to the window and feed its delta into scroll_layer_set_content_offset() to scroll the content by finger:
static ScrollLayer *s_scroll;
static int16_t s_base; // content offset committed on Complete
static void pan_handler(const Recognizer *recognizer, RecognizerEvent event) {
switch (event) {
case RecognizerEvent_Updated: {
// delta_since_start is (0, 0) at Start, so the content does not jump.
GPoint d = pan_recognizer_get_delta_since_start(recognizer);
scroll_layer_set_content_offset(s_scroll, GPoint(0, s_base + d.y), false);
break;
}
case RecognizerEvent_Completed:
s_base = scroll_layer_get_content_offset(s_scroll).y; // commit
break;
case RecognizerEvent_Cancelled:
scroll_layer_set_content_offset(s_scroll, GPoint(0, s_base), true); // roll back
break;
default:
break;
}
}
static void window_load(Window *window) {
Layer *root = window_get_root_layer(window);
s_scroll = scroll_layer_create(layer_get_bounds(root));
scroll_layer_set_content_size(s_scroll, GSize(layer_get_bounds(root).size.w,
total_content_height));
// Add your custom row layers as children of s_scroll here.
layer_add_child(root, scroll_layer_get_layer(s_scroll));
// The window owns the recognizer and destroys it when the window unloads.
Recognizer *pan = pan_recognizer_create(pan_handler, NULL, PanAxis_Vertical);
window_attach_recognizer(window, pan);
}
Create a tap recognizer. The default recognizer recognizes a single tap from a single finger.
event callback
user data associated with recognizer
recognizer reference
Create a pan recognizer locked to a single axis. The recognizer stays in the Possible state until the finger moves unambiguously along axis and crosses the start threshold, at which point it Starts. It Fails if the finger instead moves unambiguously along the foreign axis.
event callback
user data associated with recognizer
axis to which the pan is locked
recognizer reference
Create a swipe recognizer that accepts the directions set in direction_mask. The recognizer stays Possible while tracking the path and Completes on liftoff if the path is a fast, straight, long-enough flick whose direction is in the mask; otherwise it Fails.
event callback
user data associated with recognizer
bitwise-OR of the SwipeDirection values to accept
recognizer reference
Get the coordinate of the recognized tap. The coordinate is taken from the last position update, not the liftoff. Valid once the recognizer has completed.
recognizer from which to get the tap coordinate
tap coordinate
Get the total movement of the pan since the touchdown point. Component-wise.
recognizer from which to get the delta
total delta from touchdown
Get the movement of the pan since it Started (i.e. since the start threshold was crossed). This is exactly (0, 0) at the instant the recognizer transitions to Started, so live scroll that consumes this value does not jump at gesture start. Component-wise.
recognizer from which to get the delta
delta since the pan started
Get the movement of the pan since the previous position update. Component-wise.
recognizer from which to get the delta
delta since the previous event
Get the current velocity of the pan, in pixels per second, component-wise. Computed over the most-recent events within a short time window (see PAN_VELOCITY_WINDOW_MS). Zero when the elapsed time across the sampled events is zero.
recognizer from which to get the velocity
velocity in px/s
Get the recognized swipe direction. Valid once the recognizer has Completed; otherwise SwipeDirection_None.
recognizer from which to get the direction
recognized swipe direction
Get the velocity of the swipe, in pixels per second, component-wise. Computed over the most-recent events within a short time window. Zero when the elapsed time is zero.
recognizer from which to get the velocity
velocity in px/s
Destroy an un-owned recognizer. If a recognizer is not owned, this will destroy the recognizer freeing it's data and calling the destructor (see recognizer_set_on_destroy), if set. If it is owned, this will do nothing.
Gesture Recognizers to destroy
Specify a callback to determine whether a recognizer should be evaluated simultaneously with another recognizer.
recognizer to modify
callback that determines whether this recognizer will be evaluated simultaneous with another recognizer
Tell a recognizer to only evaluate after the another recognizer fails.
recognizer to modify
recognizer after which the modified gesture will be evaluated
Axis to which a pan recognizer is locked. A pan is only recognized when the finger moves unambiguously along this axis.
Swipe direction, also used as a bitmask when configuring which directions a swipe recognizer accepts. Screen coordinates grow downward, so a positive y delta is a downward swipe.
User event callback. When a recognizer changes state to any state other than the failed state the user callback of this type will be called.
recognizer affected by the event
event that occurred
This function is called to determine whether recognizer should be evaluated simultaneously with simultaneous_with.
recognizer to be tested
recognizer with which recognizer would be evaluated simultaneously should this test pass
true if recognizers should be evaluated simultaneously
Do you have questions about the Pebble SDK?
Do you need some help understanding something on this page?
You can either take advantage of our awesome developer community and check out the SDK Help forums, or you can join us on the Discord!