Skip to content

CollectionView2 Header Overlaps Items on iOS When Resized #28541

@vikher

Description

@vikher

Description

Description

In a .NET MAUI app, when the size of a CollectionView header increases dynamically (e.g., via an Expander or custom view), the header overlaps the items below it on iOS. This issue does not occur on Android, where the layout adjusts correctly. The problem is specific to the new CollectionViewHandler2 (CollectionView V2) implementation. When using the legacy CollectionView V1, the behavior is as expected, with no overlap.

In my example, I have a TheaterInfoView with an Expander in the CollectionView.Header. When this view expands or collapses (e.g., on a tap), the header size changes. With CollectionView V1, the items shift down appropriately. With CollectionView V2, the header grows over the items, obscuring them.

Related Work: This appears related to Issue #20538, which was closed, but the problem persists in my scenario with MAUI 9.0.50 and CollectionView V2.

Steps to Reproduce

  1. Create a .NET MAUI app targeting iOS.
  2. Add a CollectionView with a HeaderTemplate containing a view whose size can change (e.g., an Expander )
  3. Enable CollectionView V2 by adding this line in MauiProgram.cs:
    handlers.AddHandler<Microsoft.Maui.Controls.CollectionView,Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2>();
  4. Run the app on iOS.
  5. Increase the size of the header (e.g., expand the Expander ).
  6. Observe that the header overlaps the CollectionView items instead of pushing them down.

Expected Behavior

The CollectionView items should shift downward when the header size increases, maintaining a non-overlapping layout, as seen with CollectionView V1 and on Android.

Actual Behavior

On iOS with CollectionView V2, the header overlaps the items when its size increases, making the items partially or fully obscured.

Sample code:

<views:CnkContentPage.Content>
        <RefreshView
            x:Name="Refresher"
            Command="{Binding PullRefreshCommand}"
            IsRefreshing="{Binding IsPullRefreshing}">
            <Grid RowDefinitions="Auto,*">

                <CollectionView
                    x:Name="MainListView"
                    Grid.Row="0"
                    Grid.RowSpan="2"
                    Margin="0,0,0,25"
                    ItemSizingStrategy="MeasureAllItems"
                    IsVisible="{Binding IsOnline}"
                    IsEnabled="{Binding IsBusy, Converter={StaticResource InvertedBool}}"
                    ItemTemplate="{StaticResource TemplateSelector}"
                    ItemsSource="{Binding ListData.ListItems}"
                    SelectionMode="None">

                    <CollectionView.Header>

                        <Grid
                            x:Name="HeaderStack"
                            RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"
                            ColumnDefinitions="*"
                            RowSpacing="10"
                            HorizontalOptions="Fill">
                            <views:TheaterInfoView x:Name="TheaterInfo" Grid.Row="0" />

                            <VerticalStackLayout
                                Grid.Row="1"
                                IsClippedToBounds="True"
                                Spacing="20"
                                IsVisible="{Binding ShowFEC_Banners}"
                                Margin="0,0,0,20"
                                BindableLayout.ItemsSource="{Binding FEC_Banners}">
                                <BindableLayout.ItemTemplate>
                                    <DataTemplate>
                                        <views:FECBannerView />
                                    </DataTemplate>
                                </BindableLayout.ItemTemplate>
                            </VerticalStackLayout>

                            <views:BulletinView x:Name="TheaterBulletin" IsVisible="{Binding ShowTheaterBulletin}"
                                                Grid.Row="2" />
                            <views:FeaturedMoviesView x:Name="FeaturedMovies" Grid.Row="3" />
                            <views:TheaterAmenitiesView x:Name="TheaterAmenities" Grid.Row="4" />
                            <views:PromosView x:Name="Promos" Grid.Row="5" />

                            <Grid
                                Grid.Row="6"
                                RowDefinitions="*"
                                ColumnDefinitions="*,Auto"
                                Margin="20,0,0,0">
                                <custom:ThemeLabel
                                    x:Name="ShowtimesHeader"
                                    Grid.Row="0"
                                    Grid.Column="0"
                                    HeightRequest="40"
                                    VerticalOptions="Center"
                                    LabelStyle="HeaderLarge"
                                    Text="Showtimes" />

                                <views:ShowtimeSortModeView
                                    x:Name="ShowtimeSortModeView"
                                    Grid.Row="0"
                                    HorizontalOptions="End"
                                    Grid.Column="1" />

                            </Grid>

                            <views:ShowDateSelectorView Grid.Row="7"
                                                        x:Name="ShowDateSelector" />

                        </Grid>
                    </CollectionView.Header>

                </CollectionView>

                <VerticalStackLayout
                    x:Name="LockedHeaderStack"
                    BackgroundColor="{AppThemeBinding Light={StaticResource backgroundColor_1}, Dark={StaticResource backgroundColor_2}}"
                    Grid.Row="0" />

                <views:OfflineView
                    x:Name="OfflineView"
                    Grid.Row="0"
                    Grid.RowSpan="2"
                    Margin="0,0,0,20"
                    IsVisible="{Binding IsOnline, Converter={StaticResource InvertedBool}}" />

                <ActivityIndicator
                    IsVisible="{Binding IsBusy}"
                    Margin="0,0,0,0"
                    Grid.Row="0"
                    Color="{AppThemeBinding Light={StaticResource RedColor}, Dark={StaticResource lightGray}}"
                    HeightRequest="30"
                    WidthRequest="30"
                    IsRunning="true"
                    HorizontalOptions="Center"
                    VerticalOptions="Center" />

            </Grid>

        </RefreshView>
    </views:CnkContentPage.Content>

Link to public reproduction project repository

https://github.com/billreiss/CollectionViewOverlappingIssue

Version with bug

9.0.50 SR5

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 18

Did you find any workaround?

Disable CollectionView V2 by commenting out or removing:

handlers.AddHandler<Microsoft.Maui.Controls.CollectionView,Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2>();

This reverts to the legacy CollectionViewHandler (V1), which handles header size changes correctly on iOS.

CollectionView V1 (Legacy)

CollectionViewv1.mp4

CollectionView V2 (New)

CollectionViewv2.mp4

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-controls-collectionviewCollectionView, CarouselView, IndicatorViewcollectionview-cv2partner/syncfusionIssues / PR's with Syncfusion collaborationplatform/ioss/triagedIssue has been revieweds/try-latest-versionPlease try to reproduce the potential issue on the latest public versions/verifiedVerified / Reproducible Issue ready for Engineering Triaget/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions