#20880 - added swipe gesture support for SplitView and enabled it by …#20881
#20880 - added swipe gesture support for SplitView and enabled it by …#20881gentledepp wants to merge 1 commit intoAvaloniaUI:masterfrom
Conversation
…led it by default on mobile platforms
|
You can test this PR using the following package version. |
|
@alexander.marek, Please read the following Contributor License Agreement (CLA). If you agree with the CLA, please reply with the following: Contributor License AgreementContribution License AgreementThis Contribution License Agreement ( “Agreement” ) is agreed to by the party signing below ( “You” ), 1. Definitions. “Code” means the computer software code, whether in human-readable or machine-executable form, “Project” means any of the projects owned or managed by AvaloniaUI OÜ and offered under a license “Submit” is the act of uploading, submitting, transmitting, or distributing code or other content to any “Submission” means the Code and any other copyrightable material Submitted by You, including any 2. Your Submission. You must agree to the terms of this Agreement before making a Submission to any 3. Originality of Work. You represent that each of Your Submissions is entirely Your 4. Your Employer. References to “employer” in this Agreement include Your employer or anyone else 5. Licenses. a. Copyright License. You grant AvaloniaUI OÜ, and those who receive the Submission directly b. Patent License. You grant AvaloniaUI OÜ, and those who receive the Submission directly or c. Other Rights Reserved. Each party reserves all rights not expressly granted in this Agreement. 6. Representations and Warranties. You represent that You are legally entitled to grant the above 7. Notice to AvaloniaUI OÜ. You agree to notify AvaloniaUI OÜ in writing of any facts or 8. Information about Submissions. You agree that contributions to Projects and information about 9. Governing Law/Jurisdiction. This Agreement is governed by the laws of the Republic of Estonia, and 10. Entire Agreement/Assignment. This Agreement is the entire agreement between the parties, and AvaloniaUI OÜ dedicates this Contribution License Agreement to the public domain according to the Creative Commons CC0 1. alexander.marek doesn't seem to be a GitHub user. |
|
@cla-avalonia agree |
|
This is a complete re-implementation of the "swipe" detection algorithm and a lot of special handling code. Instead, it should be using the existing swipe gesture which should simplify a lot and significantly improve maintainability. I suspect we can get the same functionality with just a few lines of code. The idea is pretty good though. This is good functionality to have in the SplitView. |
|
that would be awesome! Can you point me to the right direction? I was not aware that a swipe gesture already exists. |
|
Yea, the documents don't list all of them and several are brand-new including swipe: You should be able to search the code base for examples in the ControlCatalog for how its used as well. |
|
No, this recognizer doesn't cover what I need. It's a one-shot swipe detector — it fires a single event once the threshold is crossed, then stops tracking. Edge-zone filtering (only start from the screen edge) What's missing for my use case: No continuous drag updates. Once the threshold is met, it raises one SwipeGestureEvent and sets _tracking = null. I never get intermediate position deltas to translate my menu panel in real time. I need something like a GestureDelta / GestureUpdated event firing on every PointerMoved after recognition. In essence I need a recognizer that transitions through phases — idle → detecting → dragging → ended — and raises three event types: something like SwipeDragStarted, SwipeDragDelta (on every move), and SwipeDragCompleted (on release, including velocity). Think of it as the horizontal equivalent of Avalonia's built-in PullGestureRecognizer / ScrollGestureRecognizer which already do exactly this pattern for scrolling. Here's what I need my side menu gesture recognizer to do: Drag the menu with my finger. As I swipe from the edge, the side menu should follow my finger in real time — not just detect a swipe and jump open. I need continuous position updates throughout the entire drag. In short: touch near the edge → drag the menu with me → on release, decide based on distance or velocity whether to animate open or animate closed. |
|
Note: the swipe detection will be improved with #20659, soon to be merged. It provides velocity tracking and a "swipe ended" gesture. |
|
Compared to using the existing |
…default on mobile platforms
What does the pull request do?
Add built-in swipe gesture support to Avalonia's
SplitViewcontrol, allowing users to open and close the pane by dragging from the pane edge. This is a common UX pattern on Android, iOS, and Windows for navigation drawers and side panels.What is the current behavior?
Users have to click a button to open/close the splitview pane
What is the updated/expected behavior with this PR?
Now you can use a swipe gesture
How was the solution implemented (if it's not obvious)?
New properties on
SplitViewIsSwipeToOpenEnabled(bool, default:false) — Opt-in property to enable swipe gesture handling. Consumers must explicitly set this totrue.IsSwipeGestureActive(bool, read-only) — Indicates whether a swipe gesture is currently in progress (dragging or snap-animating). External code (e.g.PaneClosingevent handlers) can check this to avoid interfering with the gesture.Swipe gesture behavior
Supports all four pane placements: Left, Right, Top, Bottom — including RTL layouts.
Swipe-to-open (pane closed):
Width(orHeight) is set directly as a local value, tracking the finger/pointer positionSwipe-to-close (pane open):
Snap animation: 200ms with cubic ease-out easing.
Technical approach
Width/Heightmanipulation: During drag, the pane panel (PART_PaneRoot) has itsWidthorHeightset as a local value, which overrides the style-set value (local priority > style priority in Avalonia).DoubleTransitionon Width/Height would fight the drag. On direction lock, an emptyTransitionscollection is set as a local value on the pane, suppressing animations. On finalize, this local value is cleared so the theme transitions resume.PointerReleasedOutsidehandler (which closes the pane when clicking outside in overlay mode) checksIsSwipeGestureActiveand skips during gesture to prevent the pane from closing mid-swipe.IsPaneOpenis set viaSetCurrentValueso normal coercion,PaneClosing/PaneOpenedevents, and pseudo-class updates all fire as expected. The local Width/Height override is then cleared, handing control back to the style system.Compatibility
netstandard2.0,net6.0,net8.0netstandard2.0(no[^1]index, noTimeSpan / TimeSpan)PointerType.TouchandPointerType.MouseinputChecklist
Breaking changes
Obsoletions / Deprecations
Fixed issues
Fixes #20880