Skip to content

Comments

[ios] Force going through begin in state manager#3979

Open
akwasniewski wants to merge 6 commits intomainfrom
@akwasniewski/ios-state-manager-dont-rely-on-reset
Open

[ios] Force going through begin in state manager#3979
akwasniewski wants to merge 6 commits intomainfrom
@akwasniewski/ios-state-manager-dont-rely-on-reset

Conversation

@akwasniewski
Copy link
Contributor

@akwasniewski akwasniewski commented Feb 16, 2026

Description

The state manager was not functioning correctly on iOS because the state change from begin to activate did not go through begin. handleStateChange doesn't call handleGesture for activate directly as it bypasses gesture interaction system. Instead it relies on the activate gesture being called from reset.

It worked previously, but after commit c6051ca introduced a direct check in handleGesture to determine whether it was invoked from reset. As a result, manually handled gestures were never activated.

Test plan

Tested on the StateManager example.

@j-piasecki
Copy link
Member

Are you sure this doesn't remove all gesture relations on iOS?

@akwasniewski
Copy link
Contributor Author

Are you sure this doesn't remove all gesture relations on iOS?

Ok, I trusted xcode, which said nobody calls those functions and they don't overload anything... I assumed they were obsolete, but I see they are indeed overloads from some iOS functions. My example which used gesture relations was also unaffected, neither was pressable but I see the lock example does not work now.

@akwasniewski akwasniewski marked this pull request as draft February 17, 2026 09:11
@akwasniewski akwasniewski marked this pull request as ready for review February 17, 2026 10:50
@akwasniewski
Copy link
Contributor Author

Are you sure this doesn't remove all gesture relations on iOS?

Ok, in a89a631 I fixed StateManager by simply forcing states to go through the begin state. It still relies on activate being handled in reset, which does not seem clean, but I don't see a better way around it.

@akwasniewski akwasniewski changed the title [ios] Not relying on reset in state manager [ios] Force going through beigin in state manager Feb 17, 2026
} else if (state == 4) { // ACTIVE
if (handler.recognizer.state == 0) {
// Force going from UNDETERMINED to ACTIVE through BEGAN to preserve the correct state transition flow.
[self setGestureStateSync:2 forHandler:handlerTag];
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[self setGestureStateSync:2 forHandler:handlerTag];
handler.recognizer.state = RNGHGestureRecognizerStatePossible;

Wouldn't this work? I don't see anything else done for the "2" path, so instead of going through the entire flow of finding the gesture and ensuring it's set up correctly twice, we can just change the state directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would work, but we still need to call handleGesture for begin, I thought that using recursion is cleaner here, but I agree having to find handler again adds unnecessary complexity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copilot AI review requested due to automatic review settings February 18, 2026 11:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes iOS manual gesture activation via GestureStateManager by ensuring the ACTIVE transition doesn’t bypass the expected BEGAN flow, addressing a regression introduced by the recent “fromReset” handling change.

Changes:

  • When setting a handler to ACTIVE, force an initial state progression that triggers the handler’s gesture processing path instead of bypassing it.
  • Preserve the expected state transition ordering so manually handled gestures can activate correctly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 225 to 229
if (handler.recognizer.state == 0) {
// Force going from UNDETERMINED to ACTIVE through BEGAN to preserve the correct state transition flow.
handler.recognizer.state = RNGHGestureRecognizerStatePossible;
[handler handleGesture:handler.recognizer fromReset:NO];
}
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The condition handler.recognizer.state == 0 relies on a magic number (and the comment calls it UNDETERMINED, but 0 corresponds to the platform recognizer “possible” state). This makes the intent unclear and is easy to misread/port incorrectly. Consider comparing against the explicit platform constant (with #if !TARGET_OS_OSX / #else), and update the comment to describe that this branch is about the recognizer being in Possible (used here as a proxy for “no prior BEGAN dispatch”) before forcing a BEGAN dispatch prior to activation.

Copilot uses AI. Check for mistakes.
} else if (state == 4) { // ACTIVE
if (handler.recognizer.state == 0) {
// Force going from UNDETERMINED to ACTIVE through BEGAN to preserve the correct state transition flow.
handler.recognizer.state = RNGHGestureRecognizerStatePossible;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does setting state here work? As far as I remember, recognizers are quite strict when it comes to setting state and doing so outside onTouches* doesn't work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it does. This method always relied on setting the state directly.

} else if (state == 3) { // CANCELLED
handler.recognizer.state = RNGHGestureRecognizerStateCancelled;
} else if (state == 4) { // ACTIVE
if (handler.recognizer.state == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we please check for appropriate value from UIGestureRecognizerState?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@akwasniewski akwasniewski changed the title [ios] Force going through beigin in state manager [ios] Force going through begin in state manager Feb 19, 2026
@akwasniewski akwasniewski force-pushed the @akwasniewski/ios-state-manager-dont-rely-on-reset branch from 8849fdd to caefa77 Compare February 19, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants