When a ListView is inside a container (a Frame, StackLayout, etc.) that has a gesture recognizer, the list view doesn't work. Scrolling doesn't work, tap event are not fired, etc.
var frame = new Frame();
var listView = new ListView()
{
ItemsSource = new[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6" }
};
listView.ItemTapped += async (sender, e) => await DisplayAlert("Alert", $"{e.Item} tapped", "Close");
// Removing this line makes the "ItemTapped" event work again
frame.GestureRecognizers.Add(new TapGestureRecognizer());
frame.Content = listView;
In the above code, the ItemTapped event is not fired when tapping an item (neither does ItemSelected). It's also impossible to scroll the list view.
This works fine on Android and UWP.
Here is a very simple solution file that demonstrates the bug.
Dupe of #2299
This is not a duplicate of #2299. The other bug is about a gesture recognizer inside the listview. This one is about a listview inside a container that has a gesture recognizer. Totally different
Again, @jassmith , why was this closed? As I said in the previous comment, it's a completely different case than the one it is supposedly a duplicate of.
Please @jassmith , could you at least explain why you think this is a duplicate of #2299, because I'm pretty sure it's not even related. I could be wrong, but at least provide some context instead of closing a major bug without so much as a comment.
This bug that makes ListView unusable on iOS in some scenarios. One of the scenarios is when using a list view in a popup contained in a (semi-)transparent background view with a tap gesture recognizer to allow tapping outside the popup to close the popup.
Indeed, @jassmith, what are the chances the fix in #2299 will be only partial?
Not to worry! We will create a test case for this while fixing the other issue to ensure that we fix both issues. Thanks!
Grr, I put the wrong issue number in the wrong pull request!
Unfortunately, the associated pull request does not resolve this issue, as expected. I do have a lead on how to resolve this issue, however, so a fix is forthcoming. Sorry for the confusion and thank you for your patience!
@samhouts did your lead resolve this issue? If so, is it likely to surface in a build anytime soon? This is a major blocker for a project we're working on right now, so would like an ETA (even if very rough). Thanks
This is still an issue in 3.6.0. The listview will now scroll, but the ItemTapped event never fires. This works fine on UWP and Android.
This issue doesn't seem to have had any activity in a long time. We're working on prioritizing issues and resolving them as quickly as we can. To help us get through the list, we would appreciate an update from you to let us know if this is still affecting you on the latest version of Xamarin.Forms, since it's possible that we may have resolved this as part of another related or duplicate issue. If we don't see any new activity on this issue in the next 30 days, we'll evaluate whether this issue should be closed. Thank you!
@samhouts We have implemented a workaround in our project for this issue so I don't know if it's still an issue. I'll test it in the next few days
Thanks!!
@samhouts I just tested this again and it's still an issue. The behavior hasn't changed at all. This can easily be verified in the test project I attached earlier.
@activa Thank you so much for verifying!
@samhouts I looked into this issue and found that it's caused by this method in EventTracker.cs:
bool ShouldReceiveTouch(UIGestureRecognizer recognizer, UITouch touch)
{
if (touch.View is IVisualElementRenderer)
{
return true;
}
// If the touch is coming from the UIView our renderer is wrapping (e.g., if it's
// wrapping a UIView which already has a gesture recognizer), then we should let it through
// (This goes for children of that control as well)
if (_renderer?.NativeView == null)
{
return false;
}
if (touch.View.IsDescendantOfView(_renderer.NativeView) && touch.View.GestureRecognizers?.Length > 0)
{
return true;
}
return false;
}
Note the line checking for touch.View.GestureRecognizers.Length > 0 . This returns true when tapping a cell in a listview that is wrapped in a container that also has a tap gesture recognizer. The reason is that a iOS table cell always has a default UIGestureRecognizer to handle long presses.
An easy fix would be to check if touch.View is a view cell, and return false if it is. I don't know enough about the code base to be sure it won't break something else. I did test this "fix" and it works as expected in the test cases I ran.