xamarin/Xamarin.Forms

[Bug][iOS] TapGestureRecognizer overrides CollectionView touch events. (iOS)

Open

#8,711 opened on Nov 28, 2019

 (7 comments) (1 reaction) (0 assignees)C# (1,926 forks)batch import
a/collectionviewa/gestures 🖖e/3 :clock3:help wantedinactivem/high impact :black_large_square:p/iOS 🍎partner/cat 😻t/bug :bug:up-for-grabs

Repository metrics

Stars
 (5,644 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

###Description If a parent view has a TabGestureRecognizer then the CollectionView touch events aren't fired. For example both the SelectionChangeCommand isn't fired nor is the SelectedItem updated. Also this could be any parent view in the chain of views, doesn't have to be a direct parent as it seems views pass TabGestureRecognizer event along to children

Steps to Reproduce

View

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="SelectionChangeIssue.MainPage">
    <StackLayout BackgroundColor="Green">
        <StackLayout.GestureRecognizers>
            <TapGestureRecognizer Command="{Binding StackTappedCommand}"/>
        </StackLayout.GestureRecognizers>

        <StackLayout InputTransparent="False" Margin="20" Padding="80" BackgroundColor="Red">
            <CollectionView ItemsSource="{Binding TestItems}" 
                            SelectionMode="Single" 
                            SelectionChangedCommand="{Binding SelectionChangedCommand}" 
                            SelectedItem="{Binding SelectedTestItem}" 
                            BackgroundColor="LightSteelBlue">
                <CollectionView.ItemsLayout>
                    <ListItemsLayout Orientation="Vertical" ItemSpacing="3"/>
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Label BackgroundColor="Green" 
                               TextColor="White" 
                               Text="{Binding .}" 
                               HeightRequest="40" 
                               HorizontalTextAlignment="Center" 
                               VerticalTextAlignment="Center"/>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
           
        </StackLayout>
    </StackLayout>
</ContentPage>

ViewModel

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;

namespace SelectionChangeIssue
{
    public class MainPage_ViewModel : INotifyPropertyChanged
    {
        public MainPage_ViewModel()
        {
            SelectionChangedCommand = new Command(async () => await Application.Current.MainPage.DisplayAlert("CollectionView", "CollectionView Selection Changed to " + SelectedTestItem, "OK"));
            StackTappedCommand = new Command(async () => await Application.Current.MainPage.DisplayAlert("StackLayout", "StackLayout Tapped", "OK"));

            TestItems = new ObservableCollection<string>
            {
                "Item 1",
                "Item 2",
                "Item 3",
                "Item 4",
                "Item 5",
                "Item 6",
                "Item 7",
                "Item 8",
                "Item 9",
                "Item 10"
            };
        }

        private ObservableCollection<string> _testItems;
        public ObservableCollection<string> TestItems
        {
            get { return _testItems; }
            set
            {
                if (_testItems != value)
                {
                    _testItems = value;
                    OnPropertyChanged(nameof(TestItems));
                }
            }
        }

        private string _selectedTestItem;
        public string SelectedTestItem
        {
            get { return _selectedTestItem; }
            set
            {
                if (_selectedTestItem != value)
                {
                    _selectedTestItem = value;
                    OnPropertyChanged(nameof(SelectedTestItem));
                }
            }
        }



        public ICommand SelectionChangedCommand { get; protected set; }
        public ICommand StackTappedCommand { get; protected set; }


        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var changed = PropertyChanged;
            if (changed != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Expected Behavior

The touching a Cell on the CollectionView should select an item and run the attached command.

Actual Behavior

the TapGestureRecognizer is raised instead of the CollectionView events

Basic Information

  • Version with issue: Xamarin.Forms 4.3.0
  • Platform Target Frameworks:
    • iOS: v4.0.30319

Contributor guide