Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] TableView's SwitchCell does not function correctly with screenreaders #10852

Open
@jackama

Description

Description

Using a native screenreader (VoiceOver on iOS; TalkBack on Android), activating a SwitchCell in a settings TableView reads out the current state of the switch (On or Off), but does not toggle it.

On Android, selecting the switch within the cell and activating it does toggle it, but activating the row does not.
On iOS, the SwitchCell cannot be toggled.

Steps to Reproduce

  1. Create a template Xamarin.Forms project
  2. Add a TableView with SwitchCells to a page as per the official example
  3. Build and deploy to a physical device (iOS or Android)
  4. Enable the device's native screenreader
  5. Navigate to the page, highlight one of the SwitchCell rows
  6. Double Tap to activate

Expected Behavior

The switch should toggle and the screenreader should announce the new switch state.

Actual Behavior

The switch does not toggle and the screenreader announces the unchanged switch state.
SwitchCell's OnChanged event does not fire (Checked with breakpoints).

  • Or -

On Android, the switch itself can be highlighted (with difficulty - the interaction area is small) and activating it does toggle the state. However, the switch does not utilise any of the SwitchCell's AutomationProperties, so it is unlabelled and unannounced - the screenreader simply annouces "On switch" or "Off switch".

Basic Information

  • Version with issue: Xamarin.Forms 4.5.0.495
  • Last known good version: N/A
  • IDE: Visual Studio Community 2019
  • Platform Target Frameworks:
    • iOS: 8.0.30703
    • Android: 9.0
    • UWP: Not tested
  • Nuget Packages:
    • Newtonsoft
    • SkiaSharp
    • Xamarin.Auth
    • Xamarin.Essentials

Workaround

Create custom SwitchCell element, handling events and bindings manually within.
Sample code for workaround:

CustomSwitchCell.xaml

<ViewCell 
    x:Class="AmanoPal.Views.CustomControls.CustomSwitchCell"
    AutomationProperties.IsInAccessibleTree="False"
    Tapped="ViewCell_Tapped"
    mc:Ignorable="d">
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <Label
            Grid.Column="0"
            Margin="18,0" 
            InputTransparent="True"
            Text="{Binding Text, Source={RelativeSource AncestorType={x:Type local:CustomSwitchCell}, Mode=FindAncestor}}"
            VerticalOptions="Center" />

        <Switch x:Name="ToggleSwitch"
            Grid.Column="1"
            Margin="4,0" 
            InputTransparent="True"
            IsToggled="{Binding IsToggled, Source={RelativeSource AncestorType={x:Type local:CustomSwitchCell}, Mode=FindAncestor}, Mode=OneWay}"
            VerticalOptions="Center" />
    </Grid>
</ViewCell>

CustomSwitchCell.xaml.cs

    public partial class CustomSwitchCell : ViewCell
    {
        public CustomSwitchCell()
        {
            InitializeComponent();
        }

        private void ViewCell_Tapped(object sender, EventArgs e) => IsToggled = !IsToggled;

        public string Text
        {
            get => (string)GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }

        public bool IsToggled
        {
            get => (bool)GetValue(IsToggledProperty);
            set => SetValue(IsToggledProperty, value);
        }

        public static readonly BindableProperty TextProperty =
            BindableProperty.Create("Text", typeof(string), typeof(CustomSwitchCell), null);

        public static readonly BindableProperty IsToggledProperty =
            BindableProperty.Create("IsToggled", typeof(bool), typeof(CustomSwitchCell), null, BindingMode.TwoWay);
    }

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions