Share via

EmptyView is not visible on the UI when no items are available in iOS platform

Sreenivasan, Sreejith 885 Reputation points
2026-06-26T07:25:04.8166667+00:00

Below is my UI:

 <Label Grid.Row="1" x:Name="_emptyLabel" IsVisible="False" Text="{ex:Localized NoAlertsArchivedText}" 
               AutomationProperties.HelpText="{ex:Localized NoAlertsArchivedText}" 
               AutomationProperties.IsInAccessibleTree="{Binding HasNoAlerts}" FontSize="Large" 
               VerticalTextAlignment="Center" HorizontalTextAlignment="Center" TextColor="Black"/>

        <ctrl:SwipeableListView 
            Grid.Row="1"
            AutomationProperties.IsInAccessibleTree="False"
            SelectedItemCommand="{Binding SelectedItemCommand, Mode=TwoWay}"
            VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
            LeftButtonEnabled="false"
            RightButtonEnabled="true"
            RightButtonCommand="{Binding UnarchiveCommand}"
            Items="{Binding ArchivedNotifications}"
            EmptyView="{x:Reference _emptyLabel}">
        </ctrl:SwipeableListView>

When no items are available the label will show on the UI and it is working fine on the android platform. Only on iOS platform this is not working. I can share the SwipeableListview handler code one to one since it is very big.

I have the same issue in another page where I am using a Grid layout with Image and Labels like below for the emptyview.

 <Grid x:Name="_stackLayout" IsVisible="False">
                <Grid.RowDefinitions>
                    <RowDefinition Height="60*" />
                    <RowDefinition Height="40*" />
                </Grid.RowDefinitions>

                <Image 
                    Grid.Row="0"
                    Margin="0,20,0,0"
                    Aspect="AspectFill"
                    AutomationProperties.IsInAccessibleTree="False"
                    Source="pic_big_empty_alerts"
                    VerticalOptions="FillAndExpand"
                    HorizontalOptions="FillAndExpand" />

                <StackLayout 
                    Grid.Row="1"
                     VerticalOptions="Center"
                     HorizontalOptions="Center">
                    
                    <Label 
                        Text="{Binding NoAlertsTitle}"
                        HorizontalTextAlignment="Center"
                        FontSize="22" />

                    <Label 
                        Text="{Binding NoAlertsDescription}"
                        HorizontalTextAlignment="Center"
                        FontSize="17" />
                </StackLayout>
            </Grid>


            <ctrl:SwipeableListView VerticalOptions="Fill" HorizontalOptions="Fill"
                                    SelectedItemCommand="{Binding SelectedItemCommand, Mode=TwoWay}"
                                    LeftButtonCommand="{Binding ReadCommand}"
                                    LeftButtonEnabled="true"
                                    RightButtonEnabled="true"
                                    RightButtonCommand="{Binding ArchiveCommand}"
                                    Items="{Binding Notifications}"
                                    AutomationProperties.IsInAccessibleTree="False"
                                    EmptyView="{x:Reference _stackLayout}" />
Developer technologies | .NET | .NET Multi-platform App UI
0 comments No comments

2 answers

Sort by: Most helpful
  1. Nancy Vo (WICLOUD CORPORATION) 6,510 Reputation points Microsoft External Staff Moderator
    2026-06-29T08:57:30.6466667+00:00

    Hi @Sreenivasan, Sreejith ,

    I have built a custom test environment to replicate your SwipeableListView scenario on iOS.

    As suspected, the root cause is the IsVisible="False" property on your external <Label> and <Grid>. While Android sometimes overrides this when assigning an EmptyView, the iOS rendering engine strictly obeys the IsVisible="False" command and refuses to render the views.

    I recommend removing the IsVisible="False" property and define your layouts inline directly inside the <ctrl:SwipeableListView.EmptyView> tags, rather than using an external x:Reference.

    You can refer to my following code example:

    Controls/SwipeableListView.cs:

    using System.Collections;
    using System.Windows.Input;
    
    namespace _5930711.Controls
    {
        public class SwipeableListView : ContentView
        {
            private CollectionView _innerList;
    
            public SwipeableListView()
            {
                _innerList = new CollectionView();
                Content = _innerList;
            }
    
            public static readonly BindableProperty ItemsProperty = BindableProperty.Create(nameof(Items), typeof(IEnumerable), typeof(SwipeableListView), propertyChanged: OnItemsChanged);
            public IEnumerable Items { get => (IEnumerable)GetValue(ItemsProperty); set => SetValue(ItemsProperty, value); }
            private static void OnItemsChanged(BindableObject bindable, object oldValue, object newValue)
            {
                if (bindable is SwipeableListView view) view._innerList.ItemsSource = (IEnumerable)newValue;
            }
    
            public static readonly BindableProperty EmptyViewProperty = BindableProperty.Create(nameof(EmptyView), typeof(object), typeof(SwipeableListView), propertyChanged: OnEmptyViewChanged);
            public object EmptyView { get => GetValue(EmptyViewProperty); set => SetValue(EmptyViewProperty, value); }
            private static void OnEmptyViewChanged(BindableObject bindable, object oldValue, object newValue)
            {
                if (bindable is SwipeableListView view) view._innerList.EmptyView = newValue;
            }
    
            public static readonly BindableProperty LeftButtonCommandProperty = BindableProperty.Create(nameof(LeftButtonCommand), typeof(ICommand), typeof(SwipeableListView));
            public ICommand LeftButtonCommand { get => (ICommand)GetValue(LeftButtonCommandProperty); set => SetValue(LeftButtonCommandProperty, value); }
    
            public static readonly BindableProperty RightButtonCommandProperty = BindableProperty.Create(nameof(RightButtonCommand), typeof(ICommand), typeof(SwipeableListView));
            public ICommand RightButtonCommand { get => (ICommand)GetValue(RightButtonCommandProperty); set => SetValue(RightButtonCommandProperty, value); }
    
            public static readonly BindableProperty SelectedItemCommandProperty = BindableProperty.Create(nameof(SelectedItemCommand), typeof(ICommand), typeof(SwipeableListView));
            public ICommand SelectedItemCommand { get => (ICommand)GetValue(SelectedItemCommandProperty); set => SetValue(SelectedItemCommandProperty, value); }
    
            public bool LeftButtonEnabled { get; set; }
            public bool RightButtonEnabled { get; set; }
        }
    }
    

    ViewModels/MainViewModel.cs:

    using System.Collections.ObjectModel;
    
    namespace _5930711.ViewModels
    {
        public class MainViewModel
        {
            public ObservableCollection<string> ArchivedNotifications { get; set; } = new ObservableCollection<string>();
            public ObservableCollection<string> Notifications { get; set; } = new ObservableCollection<string>();
    
            public bool HasNoAlerts => true;
            public string NoAlertsTitle { get; set; } = "You're all caught up!";
            public string NoAlertsDescription { get; set; } = "No new alerts at this time.";
        }
    }
    

    MainPage.xaml:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:ctrl="clr-namespace:_5930711.Controls"
                 x:Class="_5930711.MainPage">
    
        <VerticalStackLayout Spacing="20" Margin="10">
    
            <Label Text="iOS EmptyView Fix Sandbox" FontSize="20" HorizontalOptions="Center" FontAttributes="Bold"/>
    
            <ctrl:SwipeableListView
                HeightRequest="150"
                AutomationProperties.IsInAccessibleTree="False"
                SelectedItemCommand="{Binding SelectedItemCommand, Mode=TwoWay}"
                VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
                LeftButtonEnabled="false"
                RightButtonEnabled="true"
                RightButtonCommand="{Binding UnarchiveCommand}"
                Items="{Binding ArchivedNotifications}">
    
                <ctrl:SwipeableListView.EmptyView>
                    <Label Text="No Alerts Archived (Fixed)"
                           AutomationProperties.IsInAccessibleTree="{Binding HasNoAlerts}" FontSize="Large"
                           VerticalTextAlignment="Center" HorizontalTextAlignment="Center" TextColor="Black"/>
                </ctrl:SwipeableListView.EmptyView>
    
            </ctrl:SwipeableListView>
    
            <BoxView HeightRequest="2" Color="Gray" />
    
            <ctrl:SwipeableListView
                HeightRequest="300"
                VerticalOptions="Fill" HorizontalOptions="Fill"
                SelectedItemCommand="{Binding SelectedItemCommand, Mode=TwoWay}"
                LeftButtonCommand="{Binding ReadCommand}"
                LeftButtonEnabled="true"
                RightButtonEnabled="true"
                RightButtonCommand="{Binding ArchiveCommand}"
                Items="{Binding Notifications}"
                AutomationProperties.IsInAccessibleTree="False">
    
                <ctrl:SwipeableListView.EmptyView>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="60*" />
                            <RowDefinition Height="40*" />
                        </Grid.RowDefinitions>
    
                        <Image
                            Grid.Row="0" Margin="0,20,0,0" Aspect="AspectFill"
                            AutomationProperties.IsInAccessibleTree="False"
                            Source="dotnet_bot.png"
                            VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
    
                        <StackLayout
                            Grid.Row="1" VerticalOptions="Center" HorizontalOptions="Center">
                            <Label Text="{Binding NoAlertsTitle}" HorizontalTextAlignment="Center" FontSize="22" />
                            <Label Text="{Binding NoAlertsDescription}" HorizontalTextAlignment="Center" FontSize="17" />
                        </StackLayout>
                    </Grid>
                </ctrl:SwipeableListView.EmptyView>
    
            </ctrl:SwipeableListView>
    
        </VerticalStackLayout>
    </ContentPage>
    

    MainPage.xaml.cs:

    using _5930711.ViewModels;
    
    namespace _5930711
    {
        public partial class MainPage : ContentPage
        {
            public MainPage()
            {
                InitializeComponent();
                BindingContext = new MainViewModel();
            }
        }
    }
    

    User's image

    User's image

    Hope this helps. I would be happy to investigate further if needed. Thank you for your patience.

    Was this answer helpful?

    0 comments No comments

  2. Nancy Vo (WICLOUD CORPORATION) 6,510 Reputation points Microsoft External Staff Moderator
    2026-06-26T08:04:20.4633333+00:00

    Hello @Sreenivasan, Sreejith ,

    Thanks for your question.

    The issue you are experiencing happens because of the IsVisible="False" property set on your external _emptyLabel and _stackLayout controls.

    While Android's rendering engine sometimes forces these views to become visible when they are assigned as an EmptyView, the iOS rendering engine is much stricter. On iOS, when you pass a view with IsVisible="False" into the EmptyView property, the system respects your original instruction to keep it hidden. As a result, the layout is technically there, but it remains invisible to the user.

    I recommend removing the external x:Reference approach. Instead, define your EmptyView directly inline inside the SwipeableListView. This prevents the need to toggle visibility altogether.

    You can refer to these following steps:

    • Remove the external <Label> and define it directly inside <ctrl:SwipeableListView.EmptyView> like this:
    <ctrl:SwipeableListView
        Grid.Row="1"
        AutomationProperties.IsInAccessibleTree="False"
        SelectedItemCommand="{Binding SelectedItemCommand, Mode=TwoWay}"
        VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
        LeftButtonEnabled="false"
        RightButtonEnabled="true"
        RightButtonCommand="{Binding UnarchiveCommand}"
        Items="{Binding ArchivedNotifications}">
    
        <ctrl:SwipeableListView.EmptyView>
            <Label Text="{ex:Localized NoAlertsArchivedText}"
                   AutomationProperties.HelpText="{ex:Localized NoAlertsArchivedText}"
                   AutomationProperties.IsInAccessibleTree="{Binding HasNoAlerts}" FontSize="Large"
                   VerticalTextAlignment="Center" HorizontalTextAlignment="Center" TextColor="Black"/>
        </ctrl:SwipeableListView.EmptyView>
    
    </ctrl:SwipeableListView>
    
    • Similarly, I suggest removing the external <Grid x:Name="_stackLayout"> and place the entire layout inside the tags:
    <ctrl:SwipeableListView VerticalOptions="Fill" HorizontalOptions="Fill"
                            SelectedItemCommand="{Binding SelectedItemCommand, Mode=TwoWay}"
                            LeftButtonCommand="{Binding ReadCommand}"
                            LeftButtonEnabled="true"
                            RightButtonEnabled="true"
                            RightButtonCommand="{Binding ArchiveCommand}"
                            Items="{Binding Notifications}"
                            AutomationProperties.IsInAccessibleTree="False">
    
        <ctrl:SwipeableListView.EmptyView>
             <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="60*" />
                    <RowDefinition Height="40*" />
                </Grid.RowDefinitions>
    
                <Image
                    Grid.Row="0"
                    Margin="0,20,0,0"
                    Aspect="AspectFill"
                    AutomationProperties.IsInAccessibleTree="False"
                    Source="pic_big_empty_alerts"
                    VerticalOptions="FillAndExpand"
                    HorizontalOptions="FillAndExpand" />
    
                <StackLayout
                    Grid.Row="1"
                     VerticalOptions="Center"
                     HorizontalOptions="Center">
    
                    <Label
                        Text="{Binding NoAlertsTitle}"
                        HorizontalTextAlignment="Center"
                        FontSize="22" />
    
                    <Label
                        Text="{Binding NoAlertsDescription}"
                        HorizontalTextAlignment="Center"
                        FontSize="17" />
                </StackLayout>
            </Grid>
        </ctrl:SwipeableListView.EmptyView>
    
    </ctrl:SwipeableListView>
    

    Please try and let me know the results. I'd be happy to investigate further if needed.

    I hope this addresses your question. If this response was helpful, please consider following the guidance to provide feedback.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.