Skip to content

Commit

Permalink
CollectionView2 Items display issue when Header is resized on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
kubaflo committed Jan 11, 2025
1 parent 4b51243 commit 8a06644
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ public class StructuredItemsViewController2<TItemsView> : ItemsViewController2<T
public const int HeaderTag = 111;
public const int FooterTag = 222;

View _headerView;
View _footerView;
EventHandler _footerMeasureInvalidated;
EventHandler _headerMeasureInvalidated;

bool _disposed;

public StructuredItemsViewController2(TItemsView structuredItemsView, UICollectionViewLayout layout)
Expand All @@ -40,7 +45,11 @@ protected override void Dispose(bool disposing)

if (disposing)
{
if (_headerView != null)
_headerView.MeasureInvalidated -= _headerMeasureInvalidated;

if (_footerView != null)
_footerView.MeasureInvalidated -= _footerMeasureInvalidated;
}

base.Dispose(disposing);
Expand Down Expand Up @@ -115,26 +124,54 @@ void UpdateTemplatedSupplementaryView(TemplatedCell2 cell, NSString elementKind)

if (isHeader)
{
if (_headerView != null)
_headerView.MeasureInvalidated -= _headerMeasureInvalidated;

if (ItemsView.Header is View headerView)
{
_headerView = headerView;
cell.Bind(headerView, ItemsView);
}
else if (ItemsView.HeaderTemplate is not null)
{
_headerView = (View)ItemsView.HeaderTemplate.CreateContent();
cell.Bind(ItemsView.HeaderTemplate, ItemsView.Header, ItemsView);
}

_headerMeasureInvalidated = (s, e) =>
{
var indexPath = CollectionView.GetIndexPathForSupplementaryView(cell);
if (indexPath != null)
CollectionView.ReloadItems([indexPath]);
};

_headerView.MeasureInvalidated += _headerMeasureInvalidated;
cell.Tag = HeaderTag;
}
else
{
if (_footerView != null)
_footerView.MeasureInvalidated -= _footerMeasureInvalidated;

if (ItemsView.Footer is View footerView)
{
_footerView = footerView;
cell.Bind(footerView, ItemsView);
}
else if (ItemsView.FooterTemplate is not null)
{
_footerView = (View)ItemsView.FooterTemplate.CreateContent();
cell.Bind(ItemsView.FooterTemplate, ItemsView.Footer, ItemsView);
}

_footerMeasureInvalidated = (s, e) =>
{
var indexPath = CollectionView.GetIndexPathForSupplementaryView(cell);
if (indexPath != null)
CollectionView.ReloadItems([indexPath]);
};

_footerView.MeasureInvalidated += _footerMeasureInvalidated;
cell.Tag = FooterTag;
}
}
Expand Down
43 changes: 43 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25362.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?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"
x:Class="Maui.Controls.Sample.Issues.Issue25362"
x:Name="Self"
Title="Issue25362">
<Grid RowDefinitions="Auto,*">
<HorizontalStackLayout Grid.Row="0">
<Button
Command="{Binding AddCommand}"
HorizontalOptions="Center"
AutomationId="button"
Text="Add" />
</HorizontalStackLayout>

<CollectionView
Grid.Row="1"
ItemsSource="{Binding ItemList}">

<CollectionView.Header>
<VerticalStackLayout>
<VerticalStackLayout BindableLayout.ItemsSource="{Binding BindingContext.ItemListHeader, Source={x:Reference Self}}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Padding="10" Text="{Binding .}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</VerticalStackLayout>
<BoxView
Margin="0,5"
HeightRequest="2"
Color="Black" />
</VerticalStackLayout>
</CollectionView.Header>

<CollectionView.ItemTemplate>
<DataTemplate>
<Label Padding="10" Text="{Binding .}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
21 changes: 21 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25362.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.ObjectModel;
namespace Maui.Controls.Sample.Issues;

[XamlCompilation(XamlCompilationOptions.Compile)]
[Issue(IssueTracker.Github, 25362, "[iOS] CollectionView Items display issue when Header is resized", PlatformAffected.iOS)]

public partial class Issue25362 : ContentPage
{
public ObservableCollection<string> ItemList { get; }
public ObservableCollection<string> ItemListHeader { get; }

public Command AddCommand => new(() => ItemListHeader.Add($"HeaderItem{ItemListHeader.Count + 1}"));

public Issue25362()
{
InitializeComponent();
ItemList = new() { "Item1", "Item2", "Itme3" };
ItemListHeader = new() { "HeaderItem1" };
BindingContext = this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue25362 : _IssuesUITest
{
public override string Issue => "[iOS] CollectionView Items display issue when Header is resized";

public Issue25362(TestDevice device) : base(device)
{ }

[Test]
[Category(UITestCategories.CollectionView)]
public void HeaderShouldNotCollapseWithItems()
{
App.WaitForElement("button");
App.Click("button");
App.Click("button");
App.Click("button");

//The test passes of header has 4 elements that don't overlap with the collection view's items
VerifyScreenshot();
}
}

0 comments on commit 8a06644

Please sign in to comment.