Skip to content

Improve fling gestures on iOS#2851

Merged
Andrei Salavei (ASalavei) merged 9 commits into
jb-mainfrom
andrei.salavei/improve-fling
Mar 17, 2026
Merged

Improve fling gestures on iOS#2851
Andrei Salavei (ASalavei) merged 9 commits into
jb-mainfrom
andrei.salavei/improve-fling

Conversation

@ASalavei

Copy link
Copy Markdown

Move WebVelocityTracker1D to the skiko source set and rename it to the PointerVelocityTracker1D.
Add preventReversedPointerMovements option that prevents velocity tracker from returning velocity with the opposite direction to the general scroll direction.

Fixes https://youtrack.jetbrains.com/issue/CMP-9297/Fling-gestures-not-working-correctly-in-LazyColumn-on-iOS.

Release Notes

Fixes - iOS

  • Fix the scrolling inertia issue when performing short scroll gestures.
  • Fix an issue where a fling may occur unexpectedly when lifting a finger.

Comment on lines +156 to +161
if (dataPoints[sampleCount - 1] < dataPoints[0] && velocity < 0) {
return 0f
}
if (dataPoints[sampleCount - 1] > dataPoints[0] && velocity > 0) {
return 0f
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is a wrong logic: it is a normal situation when user does two-directional gesture by their intent. We need to detect only one point mistakes (as you showed).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To be honest, I still think we don't need to do that at all

@ASalavei Andrei Salavei (ASalavei) Mar 13, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The investigation showed that fixing the "one point mistake" cannot fix the expected behavior of the gesture. There are several reasons: It can be more then one point the goes on the opposite direction from the gesture direction and on 120 fps the density of events is higher (or very low in case of lags) - this approach cannot be applied in such cases.

The goal of this MR to align behavior between native iOS and Compose scrolls. Tests show that current logic helps more closely mimic the iOS scrolling experience. We can either make this behavior multiplatform or move it to the iOS codebase.
My vote here for Multiplatform solution: scroll behavior for browsers on iOS also need to be aligned with iOS experience.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you implement a pure swift app with a scroll view + touch points tracking and show how it works on iOS?

@ASalavei Andrei Salavei (ASalavei) Mar 16, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This should be more clear - here are 2 examples of gestures for iOS scroll view that finished with full scroll stop. Both are long gestures:

Gesture 1 (have points in opposite direction from general scroll):
[event] began  point=(198.3, 602.3)
[event] moved  point=(196.0, 586.3)  dt=0.029s
....
[event] moved  point=(219.3, 467.7)  dt=0.129s
[event] moved  point=(220.3, 464.0)  dt=0.145s
[event] moved  point=(221.0, 463.7)  dt=0.162s
[event] moved  point=(222.0, 466.0)  dt=0.196s // Compose will inserts synthetic move after this event
[event] ended  point=(224.3, 468.0)  dt=0.196s

Gesture 2 (points in the same direction, but slowing down):
[event] began  point=(172.7, 602.0)
[event] moved  point=(168.0, 581.3)  dt=0.047s
...
[event] moved  point=(189.0, 348.7)  dt=0.213s
[event] moved  point=(189.7, 345.7)  dt=0.230s
[event] moved  point=(192.3, 345.3)  dt=0.247s
[event] moved  point=(193.3, 345.3)  dt=0.264s // Compose will inserts synthetic move after this event
[event] ended  point=(195.3, 344.3)  dt=0.265s

…nter/util/PlatformVelocityTracker.ios.kt

Co-authored-by: Vendula Švastalová <vendula.svastalova@jetbrains.com>
…nter/util/PlatformVelocityTracker.ios.kt

Co-authored-by: Vendula Švastalová <vendula.svastalova@jetbrains.com>
@ASalavei Andrei Salavei (ASalavei) merged commit 71c87ef into jb-main Mar 17, 2026
17 checks passed
@ASalavei Andrei Salavei (ASalavei) deleted the andrei.salavei/improve-fling branch March 17, 2026 13:10
ApoloApps pushed a commit to ApoloApps/compose-multiplatform-core that referenced this pull request Mar 17, 2026
Move `WebVelocityTracker1D` to the skiko source set and rename it to the
`PointerVelocityTracker1D`.
Add `preventReversedPointerMovements` option that prevents velocity
tracker from returning velocity with the opposite direction to the
general scroll direction.

Fixes
https://youtrack.jetbrains.com/issue/CMP-9297/Fling-gestures-not-working-correctly-in-LazyColumn-on-iOS.

## Release Notes
### Fixes - iOS
- Fix the scrolling inertia issue when performing short scroll gestures.
- Fix an issue where a fling may occur unexpectedly when lifting a
finger.

---------

Co-authored-by: Vendula Švastalová <vendula.svastalova@jetbrains.com>
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.

4 participants