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 into
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34923Or
iex "& { $(irm https://raw.githubusercontent.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?
|
/review -b feature/refactor-copilot-yml -p android |
…ability (dotnet#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 dotnet#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 dotnet#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 | |----|-------------------|-------|------------| | dotnet#35037 (WebView theme) | `ViewBaseTests,WebView` | [13940071](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940071) | [comment](dotnet#35037 (comment)) | | dotnet#35031 (Shell memory leak) | `Shell` | [13940072](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940072) | [comment](dotnet#35031 (comment)) | | dotnet#35020 (XAML Hot Reload) | _(none — XAML only)_ | [13940073](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940073) | ✅ Shows "No UI test categories" | | dotnet#35008 (Shell SearchHandler) | `Shell` | [13940074](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940074) | ✅ | | dotnet#34997 (RadioButton gradient) | `RadioButton,ViewBaseTests` | [13940075](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940075) | ✅ | | dotnet#34980 (DatePicker rotation) | `ViewBaseTests` | [13940076](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940076) | ✅ | | dotnet#34974 (Picker CharacterSpacing) | `ViewBaseTests` | [13940077](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940077) | ✅ | | dotnet#34923 (SwipeView threshold) | `SwipeView,ViewBaseTests` | [13940078](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940078) | ✅ | | dotnet#34907 (CollectionView ScrollTo) | `CollectionView` | [13940079](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940079) | ✅ | | dotnet#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>
…ability (dotnet#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 dotnet#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 dotnet#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 | |----|-------------------|-------|------------| | dotnet#35037 (WebView theme) | `ViewBaseTests,WebView` | [13940071](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940071) | [comment](dotnet#35037 (comment)) | | dotnet#35031 (Shell memory leak) | `Shell` | [13940072](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940072) | [comment](dotnet#35031 (comment)) | | dotnet#35020 (XAML Hot Reload) | _(none — XAML only)_ | [13940073](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940073) | ✅ Shows "No UI test categories" | | dotnet#35008 (Shell SearchHandler) | `Shell` | [13940074](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940074) | ✅ | | dotnet#34997 (RadioButton gradient) | `RadioButton,ViewBaseTests` | [13940075](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940075) | ✅ | | dotnet#34980 (DatePicker rotation) | `ViewBaseTests` | [13940076](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940076) | ✅ | | dotnet#34974 (Picker CharacterSpacing) | `ViewBaseTests` | [13940077](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940077) | ✅ | | dotnet#34923 (SwipeView threshold) | `SwipeView,ViewBaseTests` | [13940078](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940078) | ✅ | | dotnet#34907 (CollectionView ScrollTo) | `CollectionView` | [13940079](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940079) | ✅ | | dotnet#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>
|
/review -b feature/enhanced-reviewer -p android |
|
/review tests |
|
| Failure | Verdict | Evidence |
|---|---|---|
maui-pr-uitests — Android UITests Controls (API 30) SoftInput,Stepper,Switch,SwipeView |
Needs human investigation | Category name explicitly includes SwipeView; PR modifies src/Core/src/Platform/Android/MauiSwipeView.cs and adds Android SwipeView snapshot images. Build 1437172 inaccessible (404). |
maui-pr-uitests — Android UITests CoreClr Controls (API 30) SoftInput,Stepper,Switch,SwipeView |
Needs human investigation | Same SwipeView category as above, CoreClr runtime variant. Same code overlap. Build 1437172 inaccessible (404). |
maui-pr-uitests — iOS UITests Mono Controls (vlatest) SoftInput,Stepper,Switch,SwipeView |
Needs human investigation | Category includes SwipeView; PR modifies src/Core/src/Platform/iOS/MauiSwipeView.cs and SwipeViewExtensions.cs, and adds iOS SwipeView snapshot images. Build 1437172 inaccessible (404). |
maui-pr-uitests — iOS UITests Mono CollectionView1 Controls (vlatest) |
Needs human investigation | PR adds/updates VerifyCollectionViewContentWithButtonSwipeItem.png snapshots for iOS and Android. Snapshot mismatch in CI is possible. Build 1437172 inaccessible (404). |
maui-pr-uitests — macOS UITests Controls SoftInput,Stepper,Switch,SwipeView |
Needs human investigation | Category includes SwipeView; .ios.cs files (MauiSwipeView.cs, SwipeViewExtensions.cs) compile for MacCatalyst — changes may affect macOS. Build 1437172 inaccessible (404). |
maui-pr-uitests — WinUI UITests Controls WebView (CANCELLED) |
Likely unrelated | Cancelled job from an older build (1399801, dated 2026-04-28). PR does not modify any Windows or WebView code. |
| Build Analysis | Insufficient data | Meta-check reflecting the failures above; no additional detail accessible. |
Recommended action
Review the SwipeView test failures in build 1437172 directly; the heavy overlap between failing categories and changed SwipeView code/snapshots on Android, iOS, and macOS suggests these failures are related to this PR. Confirm whether the newly added snapshot images (VerifySwipeView*, VerifyCollectionView*) match CI expectations, or if the SwipeView code changes introduced a regression.
Evidence details
PR scope:
- Changed files: 17 (14 are test/snapshot files)
- Platform code changed:
src/Core/src/Platform/Android/MauiSwipeView.cs,src/Core/src/Platform/iOS/MauiSwipeView.cs,src/Core/src/Platform/iOS/SwipeViewExtensions.cs - New tests:
src/Controls/tests/TestCases.HostApp/Issues/Issue6016.cs,src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue6016.cs - New snapshots: 6 Android snapshots + 6 iOS (ios-26) snapshots for SwipeView and CollectionView scenarios
Failing build: 1437172 (maui-pr-uitests, 2026-05-27)
- Build data: Inaccessible (404 Not Found) — no timeline records, log excerpts, or test results available.
Cancelled build: 1399801 (maui-pr-uitests, 2026-04-28) — older run, WinUI WebView job cancelled.
Data limitations:
- AzDO build REST APIs returned 404 for both builds; no authenticated AzDO token was available.
- No Helix aggregate data was present in the gathered context.
- Specific failing test names, error messages, and stack traces could not be retrieved.
- Without log access, it is not possible to distinguish between a code regression, a snapshot mismatch, or a new test that fails on the CI baseline.
Tests Failure Analysis
Test Failure Review: Needs human investigation - click to expandOverall verdict: Needs human investigation All 5 failing
Recommended actionReview the SwipeView test failures in build 1437172 directly; the heavy overlap between failing categories and changed SwipeView code/snapshots on Android, iOS, and macOS suggests these failures are related to this PR. Confirm whether the newly added snapshot images ( Evidence detailsPR scope:
Failing build: 1437172 (
Cancelled build: 1399801 ( Data limitations:
|
|
/review rerun |
|
/review -b feature/enhanced-reviewer -p android |
|
|
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