-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[Android, iOS] Fix for CollectionView and CarouselView remain interactive when disabled #32794
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[Android, iOS] Fix for CollectionView and CarouselView remain interactive when disabled #32794
Conversation
|
Hey there @@SyedAbdulAzeemSF4852! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
5f2aa59 to
aaffcbf
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a bug where CollectionView and CarouselView remain interactive when IsEnabled is set to false on iOS and Android platforms. The fix ensures these controls properly block user interactions (scrolling, swiping) when disabled, matching Windows behavior.
Key changes:
- Android: Added
Enabledproperty checks inOnInterceptTouchEventmethods to prevent touch event propagation when controls are disabled - iOS: Implemented
UpdateIsEnabledextension method that setsUserInteractionEnabledonUICollectionView, with proper handler mappings for both v1 and v2 handlers - Tests: Added UI test case verifying CarouselView respects
IsEnabledproperty
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Core/src/Platform/iOS/CollectionViewExtensions.cs | Adds UpdateIsEnabled extension method for UICollectionView to sync UserInteractionEnabled with IsEnabled property |
| src/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cs | Overrides OnInterceptTouchEvent to return false when disabled, blocking touch interactions |
| src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs | Adds Enabled check to existing swipe-enabled logic in OnInterceptTouchEvent |
| src/Controls/src/Core/Handlers/Items/ItemsViewHandler.iOS.cs | Adds MapIsEnabled static method to call UpdateIsEnabled extension |
| src/Controls/src/Core/Handlers/Items/ItemsViewHandler.cs | Registers IsEnabled property mapping for iOS/MacCatalyst platforms |
| src/Controls/src/Core/Handlers/Items/CarouselViewHandler.iOS.cs | Adds MapIsEnabled method for CarouselView handler |
| src/Controls/src/Core/Handlers/Items/CarouselViewHandler.cs | Registers IsEnabled property mapping for iOS/MacCatalyst |
| src/Controls/src/Core/Handlers/Items2/ItemsViewHandler2.iOS.cs | Adds MapIsEnabled to v2 handler implementation |
| src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs | Adds MapIsEnabled to v2 CarouselView handler |
| src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt | Documents new public override for OnInterceptTouchEvent |
| src/Controls/tests/TestCases.HostApp/Issues/Issue32791.cs | Test page demonstrating disabled CarouselView behavior |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32791.cs | UI test validating CarouselView cannot be swiped when disabled |
| #if MACCATALYST | ||
| // MacCatalyst: Wait for item transition to complete after scroll gesture | ||
| Thread.Sleep(1000); | ||
| #endif | ||
| var statusText = App.WaitForElement("Issue32791StatusLabel").GetText(); | ||
| Assert.That(statusText, Is.EqualTo("Success")); |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Platform-conditional compilation with Thread.Sleep in the test can hide test failures on MacCatalyst. If the sleep is truly necessary for MacCatalyst, consider documenting why, or better yet, use a proper wait mechanism.
According to the UI testing guidelines, tests should use App.WaitForElement or similar explicit waits rather than arbitrary sleeps. If there's a specific element state you're waiting for on MacCatalyst, wait for that explicitly.
| #if MACCATALYST | |
| // MacCatalyst: Wait for item transition to complete after scroll gesture | |
| Thread.Sleep(1000); | |
| #endif | |
| var statusText = App.WaitForElement("Issue32791StatusLabel").GetText(); | |
| Assert.That(statusText, Is.EqualTo("Success")); | |
| // Wait for the status label to display "Success" after scroll gesture | |
| App.WaitFor(() => | |
| { | |
| var label = App.FindElement("Issue32791StatusLabel"); | |
| return label != null && label.GetText() == "Success"; | |
| }, timeout: TimeSpan.FromSeconds(5)); | |
| var statusText = App.FindElement("Issue32791StatusLabel").GetText(); | |
| Assert.That(statusText, Is.EqualTo("Success")); |
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
Root Cause
Android
CollectionView : MauiRecyclerView (used by CollectionView) was not checking the Enabled property inside OnInterceptTouchEvent, which allowed touch events to continue propagating. As a result, swipe and scroll gestures still worked even when the control was disabled.
CarouselView : MauiCarouselRecyclerView already included an IsSwipeEnabled check in OnInterceptTouchEvent, but it did not check the Enabled state either, which prevented it from fully blocking interaction when IsEnabled was set to false.
iOS
Description of Change
Issues Fixed
Fixes #32791
Validated the behaviour in the following platforms
Output
Android_Before.mov
Android_After.mov
iOS_Before.mov
iOS_After.mov