Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,28 @@ protected virtual void LayoutPropertyChanged(object sender, PropertyChangedEvent
}
}

public override bool OnTouchEvent(MotionEvent e)
{
// If ItemsView is disabled, don't handle touch events
if (ItemsView?.IsEnabled == false)
{
return false;
}

return base.OnTouchEvent(e);
}

public override bool OnInterceptTouchEvent(MotionEvent e)
{
// If ItemsView is disabled, intercept all touch events to prevent interactions
if (ItemsView?.IsEnabled == false)
{
return true;
}

return base.OnInterceptTouchEvent(e);
}

protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView<TItemsView, TAdapter, TItemsViewSource>.OnInterceptTouchEvent(Android.Views.MotionEvent e) -> bool
~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView<TItemsView, TAdapter, TItemsViewSource>.OnTouchEvent(Android.Views.MotionEvent e) -> bool
93 changes: 93 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue19771.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 19771, "CollectionView IsEnabled=false allows touch interactions on iOS and Android", PlatformAffected.iOS | PlatformAffected.Android)]
public class Issue19771 : ContentPage
{
const string DisableButton = "DisableButton";
const string TestCollectionView = "TestCollectionView";
const string InteractionCountLabel = "InteractionCountLabel";
const string StatusLabel = "StatusLabel";

private int _interactionCount = 0;
private Label _interactionLabel;
private Label _statusLabel;
private CollectionView _collectionView;

public Issue19771()
{
var items = new List<string> { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };

_statusLabel = new Label
{
AutomationId = StatusLabel,
Text = "CollectionView is ENABLED",
FontSize = 16,
FontAttributes = FontAttributes.Bold,
HorizontalOptions = LayoutOptions.Center,
Margin = new Thickness(10)
};

_interactionLabel = new Label
{
AutomationId = InteractionCountLabel,
Text = "Interaction Count: 0",
FontSize = 14,
HorizontalOptions = LayoutOptions.Center,
Margin = new Thickness(5)
};

var disableButton = new Button
{
AutomationId = DisableButton,
Text = "IsEnabled=False",
HorizontalOptions = LayoutOptions.Center,
Margin = new Thickness(10)
};
disableButton.Clicked += (s, e) => SetEnabled(false);

_collectionView = new CollectionView
{
AutomationId = TestCollectionView,
Background = Colors.AliceBlue,
ItemsSource = items,
SelectionMode = SelectionMode.Single,
HeightRequest = 300,
ItemTemplate = new DataTemplate(() =>
{
var grid = new Grid { Padding = 10 };
var label = new Label { TextColor = Colors.Black };
label.SetBinding(Label.TextProperty, ".");
grid.Children.Add(label);
return grid;
})
};

_collectionView.SelectionChanged += (s, e) =>
{
_interactionCount++;
_interactionLabel.Text = $"Interaction Count: {_interactionCount}";
};

Content = new StackLayout
{
Children =
{
_statusLabel,
_interactionLabel,
new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.Center,
Children = { disableButton }
},
_collectionView
}
};
}

private void SetEnabled(bool isEnabled)
{
_collectionView.IsEnabled = isEnabled;
_statusLabel.Text = isEnabled ? "CollectionView is ENABLED" : "CollectionView is DISABLED";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue19771 : _IssuesUITest
{
public Issue19771(TestDevice device) : base(device)
{
}

public override string Issue => "CollectionView IsEnabled=false allows touch interactions on iOS and Android";

[Test]
[Category(UITestCategories.CollectionView)]
public void CollectionViewIsEnabledFalsePreventsInteractions()
{
App.WaitForElement("Item 1");
App.Tap("Item 1");
App.WaitForElement("DisableButton");
App.Tap("DisableButton");
App.WaitForElement("Item 3");
App.Tap("Item 3");
var text = App.WaitForElement("InteractionCountLabel").GetText();
Assert.That(text, Is.EqualTo("Interaction Count: 1"));
}
}
14 changes: 10 additions & 4 deletions src/Core/src/Platform/iOS/ViewExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ public static partial class ViewExtensions

public static void UpdateIsEnabled(this UIView platformView, IView view)
{
if (platformView is not UIControl uiControl)
return;

uiControl.Enabled = view.IsEnabled;
if (platformView is UIControl uiControl)
{
// UIControl has native Enabled property with visual feedback
uiControl.Enabled = view.IsEnabled;
}
else
{
// Non-UIControl views (like UICollectionView) only get interaction disable
platformView.UserInteractionEnabled = view.IsEnabled;
}
}

public static void Focus(this UIView platformView, FocusRequest request)
Expand Down
Loading