Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ const styles = StyleSheet.create({

If you want to control gesture lifecycle outside of it, you can use `handlerTag` from created gesture object.

:::note
The gestures can only be activated after it has begun, that is, after it has received received touch events.
:::

<CollapsibleCode
label="Show full example"
expandedLabel="Hide full example"
Expand Down Expand Up @@ -179,14 +183,6 @@ const styles = {

`GestureStateManager` provides methods to manipulate gesture's state imperatively.

### begin

```tsx
begin: (handlerTag: number) => void;
```

Triggers [`onBegin`](/docs/fundamentals/callbacks-events#onbegin) callback on gesture with specified `handlerTag`.

### activate

```tsx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,11 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
UiThreadUtil.assertOnUiThread()

registry.getHandler(handlerTag)?.let { handler ->
if (handler.state == GestureHandler.STATE_UNDETERMINED) {
handler.forceReinitializeDuringOnHandle = true

// When going from UNDETERMINED to ACTIVE, force going through BEGAN to preserve
// the correct state flow
if (newState == GestureHandler.STATE_ACTIVE) {
handler.begin()
if (newState == GestureHandler.STATE_ACTIVE) {
if (handler.state != GestureHandler.STATE_BEGAN) {
// We don't allow activation of gestures which haven't received any touches
return
}
}

if (newState == GestureHandler.STATE_ACTIVE || newState == GestureHandler.STATE_BEGAN) {
handler.recordHandlerIfNotPresent()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
@property (nonatomic, weak, nullable) RNGHUIView *hostDetectorView;
@property (nonatomic, nullable, assign) NSNumber *virtualViewTag;
@property (nonatomic, copy, nullable) NSNumber *viewTag;
@property (nonatomic, readonly) RNGestureHandlerState lastState;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be confusing given that we already have _lastState defined 20 lines above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lastState is just a getter for _lastState, they are automatically linked. I kept it this way to ensure subclasses can modify the value, but it remains readonly elsewhere


- (BOOL)isViewParagraphComponent:(nullable RNGHUIView *)view;
- (nonnull RNGHUIView *)chooseViewForInteraction:(nonnull UIGestureRecognizer *)recognizer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,9 @@ - (void)setGestureStateSync:(int)state forHandler:(int)handlerTag
} else if (state == 3) { // CANCELLED
handler.recognizer.state = RNGHGestureRecognizerStateCancelled;
} else if (state == 4) { // ACTIVE
if (handler.recognizer.state == UIGestureRecognizerStatePossible) {
// Force going from UNDETERMINED to ACTIVE through BEGAN to preserve the correct state transition flow.
[handler handleGesture:handler.recognizer fromReset:NO fromManualStateChange:YES];
// We don't allow activation of gestures which haven't received any touches
if (handler.lastState == RNGestureHandlerStateUndetermined) {
return;
}
[handler stopActivationBlocker];
handler.recognizer.state = RNGHGestureRecognizerStateBegan;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { State } from '../State';
import { tagMessage } from '../utils';

export type GestureStateManagerType = {
begin(handlerTag: number): void;
activate(handlerTag: number): void;
fail(handlerTag: number): void;
deactivate(handlerTag: number): void;
Expand All @@ -21,11 +20,6 @@ const setGestureState = (handlerTag: number, state: State) => {
};

export const GestureStateManager: GestureStateManagerType = {
begin(handlerTag: number) {
'worklet';
setGestureState(handlerTag, State.BEGAN);
},

activate(handlerTag: number) {
'worklet';
setGestureState(handlerTag, State.ACTIVE);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { State } from '../State';
import { tagMessage } from '../utils';
import IGestureHandler from '../web/handlers/IGestureHandler';
import GestureHandlerOrchestrator from '../web/tools/GestureHandlerOrchestrator';
Expand All @@ -16,24 +15,10 @@ function ensureHandlerAttached(handler: IGestureHandler) {
}

export const GestureStateManager: GestureStateManagerType = {
begin(handlerTag: number): void {
'worklet';
const handler = NodeManager.getHandler(handlerTag);
ensureHandlerAttached(handler);

GestureHandlerOrchestrator.instance.recordHandlerIfNotPresent(handler);
handler.begin();
},

activate(handlerTag: number): void {
'worklet';
const handler = NodeManager.getHandler(handlerTag);
ensureHandlerAttached(handler);
// Force going from UNDETERMINED to ACTIVE through BEGAN to preserve
// the correct state transition flow.
if (handler.state === State.UNDETERMINED) {
handler.begin();
}

GestureHandlerOrchestrator.instance.recordHandlerIfNotPresent(handler);
handler.activate(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export default abstract class GestureHandler implements IGestureHandler {
public activate(force = false) {
if (
(this.manualActivation !== true || force) &&
(this.state === State.UNDETERMINED || this.state === State.BEGAN)
this.state === State.BEGAN
) {
this.delegate.onActivate();
this.moveToState(State.ACTIVE);
Expand Down
3 changes: 2 additions & 1 deletion skills/gesture-handler-3-migration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ In Gesture Handler 3, `stateManager` is no longer passed to `TouchEvent` callbac

`GestureStateManager` provides methods for imperative state management:

- .begin(handlerTag: number)
- .activate(handlerTag: number)
- .deactivate(handlerTag: number) (.end() in the old API)
- .fail(handlerTag: number)
Expand All @@ -81,6 +80,8 @@ In Gesture Handler 3, `stateManager` is no longer passed to `TouchEvent` callbac

Callback definitions CANNOT reference the gesture that's being defined. In this scenario use events to get access to the handler tag.

Remove GestureStateManager.begin() as gestures must now automatically enter the BEGAN state via touch events before they can be activated through the GestureStateManager.

### Migrating relations

#### Composed gestures
Expand Down
Loading