Fix SwipeView Threshold changes width and offset of the side menu (when visible)#34923
Fix SwipeView Threshold changes width and offset of the side menu (when visible)#34923KarthikRajaKalaimani wants to merge 9 commits intodotnet:mainfrom
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://github.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34923Or
iex "& { $(irm https://github.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34923" |
|
Hey there @@KarthikRajaKalaimani! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
/azp run maui-pr-uitests , maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR fixes incorrect use of SwipeView.Threshold in the iOS and Android platform implementations so that Threshold affects only the trigger distance for opening, not the rendered swipe menu width or the final open offset.
Changes:
- iOS/Android: stop using
Thresholdto size swipe items and to determine the open snap distance; compute open distance from actual menu size and treatThresholdas a cap for the trigger distance. - iOS/Android: rename internal “threshold” helper to reflect “open distance” semantics and update call sites.
- Add a new UI test page + Appium test for Issue 6016 to validate menu width is unaffected by
Thresholdand that Execute mode still triggers.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Core/src/Platform/iOS/SwipeViewExtensions.cs | Removes Threshold from swipe-item sizing calculations on iOS. |
| src/Core/src/Platform/iOS/MauiSwipeView.cs | Uses menu open distance for snapping; uses Threshold only for trigger distance on iOS. |
| src/Core/src/Platform/Android/MauiSwipeView.cs | Mirrors iOS behavior changes on Android; removes old reveal-threshold helper and stops sizing by Threshold. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue6016.cs | Adds Appium UI coverage for the regression (menu width/offset + Execute mode). |
| src/Controls/tests/TestCases.HostApp/Issues/Issue6016.cs | Adds HostApp reproduction page used by the new UI test. |
addressed AI summary concerns |
|
/azp run maui-pr-uitests , maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
|
/azp run maui-pr-uitests , maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
kubaflo
left a comment
There was a problem hiding this comment.
Looks like some tests are failing - could you please verify?
kubaflo
left a comment
There was a problem hiding this comment.
Could you please resolve conflicts?
96ccaea to
b7df93e
Compare
resolved the conflicts |
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…ability (#35133) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! > **Depends on #35136** (pipeline category detection — should merge first) ## What this does Two things: ### 1. UI test category detection in PR review During the PR review workflow, Step 0.5 detects which UI test categories the PR impacts and writes the result to the AI summary comment. This gives reviewers visibility into which UI tests are relevant. **Detection** reuses the 3-tier script from #35136 (test attributes → source paths → AI reasoning). **AI summary** shows a new 🧪 UI Tests section with detected categories before the gate section. ### 2. Gate reliability fixes Multiple fixes to make the gate (`verify-tests-fail.ps1`) more deterministic: | Fix | Problem it solves | |-----|-------------------| | **Absolute path resolution** | Gate scripts not found on Linux CI agents (`Resolve-Path`, `GetFullPath`) | | **File existence check** | Instant cryptic failure when verify script is missing — now logs clear error | | **3x retry on ENV ERROR** | Emulator timeouts, ADB failures, app crashes — transient issues that pass on retry | | **Strip bad report blocks** | Old verify script produces `Passed: False` with empty counts — stripped instead of shown | | **Gate log in fallback** | When report is missing, shows last 20 lines of gate output instead of just `❌ FAILED / Platform: IOS` | ## Files | File | Changes | |------|---------| | `.github/scripts/Review-PR.ps1` | Step 0.5 category detection + all 5 gate fixes | | `.github/scripts/post-ai-summary-comment.ps1` | Add `uitests` phase to render detected categories | | `.github/pr-review/pr-preflight.md` | Step 7: AI identifies impacted UI test categories | ## Validation — PR reviewer builds (Apr 26) 10 builds against real PRs — all succeeded ✅. Category detection shown in AI summary comment. | PR | Categories Detected | Build | AI Summary | |----|-------------------|-------|------------| | #35037 (WebView theme) | `ViewBaseTests,WebView` | [13940071](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940071) | [comment](#35037 (comment)) | | #35031 (Shell memory leak) | `Shell` | [13940072](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940072) | [comment](#35031 (comment)) | | #35020 (XAML Hot Reload) | _(none — XAML only)_ | [13940073](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940073) | ✅ Shows "No UI test categories" | | #35008 (Shell SearchHandler) | `Shell` | [13940074](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940074) | ✅ | | #34997 (RadioButton gradient) | `RadioButton,ViewBaseTests` | [13940075](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940075) | ✅ | | #34980 (DatePicker rotation) | `ViewBaseTests` | [13940076](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940076) | ✅ | | #34974 (Picker CharacterSpacing) | `ViewBaseTests` | [13940077](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940077) | ✅ | | #34923 (SwipeView threshold) | `SwipeView,ViewBaseTests` | [13940078](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940078) | ✅ | | #34907 (CollectionView ScrollTo) | `CollectionView` | [13940079](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940079) | ✅ | | #34845 (RefreshView binding) | `RefreshView,ViewBaseTests` | [13940080](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940080) | ✅ | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 7 findings
See inline comments for details.
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details:
SwipeView Threshold changes width and offset of the side menu (when visible) Opened.
Root Cause:
The SwipeView.Threshold property is designed for a single purpose: setting the minimum drag distance a user must swipe before the menu snaps open. It has nothing to do with how wide the menu
items should appear or where the content settles after the swipe. However, the platform code on both iOS and Android was incorrectly using this value in two unrelated calculations.
The first misuse was in GetSwipeItemSize(), where the code checked if Threshold > 0 and, if so, used the threshold value as the item's width. This meant that setting Threshold=200 would inflate
every swipe item to 200pt wide, far larger than the intended ~100pt. The second misuse was in GetSwipeThreshold(ISwipeItems), which had an early return that directly handed back the Threshold
value as the snap-open distance. So the content would snap to 200pt offset instead of snapping to the actual menu width. Together, these two bugs caused both the menu to look bloated and the
content displacement to differ depending on whether Threshold was set.
Description of Change:
The fix removes Threshold from both of those calculations entirely. Item sizing now uses only the item's configured WidthRequest or the default SwipeItemWidth, as it should. The snap distance is now computed as Math.Min(Threshold, menuWidth) — meaning if Threshold is set, it acts as a cap on how far the user needs to drag, but the content still snaps to the true menu width. If Threshold is not set, the default behaviour of 60% of menu width is preserved. This was applied consistently across iOS (MauiSwipeView.cs and SwipeViewExtensions.cs) and Android (MauiSwipeView.cs).
Tested the behavior in the following platforms:
Reference:
N/A
Issues Fixed:
Fixes #6016
Screenshots
Before_fix_6016.mov
After_fix_6016.mov