[iOS] Fix MeasureFirstItem for CollectionView (#7622)

* fix MeasureFirstItem

* added test

* changed file name

* fix path

* added text

* remove 5455

* drop private
fixes #7621
This commit is contained in:
adrianknight89 2019-09-26 19:16:03 -05:00 коммит произвёл Samantha Houts
Родитель dd11b6e943
Коммит c09c373e97
6 изменённых файлов: 166 добавлений и 4 удалений

Просмотреть файл

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<controls:TestContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:Xamarin.Forms.Controls"
x:Class="Xamarin.Forms.Controls.Issues.Issue7621">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Margin="10" Spacing="10" Orientation="Vertical" BackgroundColor="Beige">
<Label LineBreakMode="WordWrap" Text="Verify that all Frames have the same width and height. Scroll to the end of CollectionView and back. Verify that item sizes do not change. If so, MeasureFirstItem is working." HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label LineBreakMode="WordWrap" Text="MeasureAllItems is not part of this test, but you could switch to it for manual testing." HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Button Text="Switch to MeasureAllItems" HorizontalOptions="Center" VerticalOptions="Center" Clicked="ButtonClicked"/>
</StackLayout>
<CollectionView Grid.Row="1" ItemSizingStrategy="MeasureFirstItem" ItemsSource="{Binding Items}">
<CollectionView.ItemsLayout>
<GridItemsLayout Span="2" Orientation="Horizontal" HorizontalItemSpacing="5" VerticalItemSpacing="5"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame CornerRadius="5" HasShadow="False" Padding="10" BackgroundColor="{Binding BackgroundColor}">
<Image Source="{Binding Source}" Aspect="AspectFit"/>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</controls:TestContentPage>

Просмотреть файл

@ -0,0 +1,104 @@
using System.Collections.ObjectModel;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using System;
using Xamarin.Forms.Xaml;
using System.Threading;
using System.Collections.Generic;
using System.Threading.Tasks;
#if UITEST
using Xamarin.UITest;
using Xamarin.UITest.Queries;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
using System.Linq;
#endif
namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.CollectionView)]
#endif
#if APP
[XamlCompilation(XamlCompilationOptions.Compile)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 7621, "[iOS] MeasureFirstItem is broken for CollectionView", PlatformAffected.iOS)]
public partial class Issue7621 : TestContentPage
{
bool isMeasuringAllItems = false;
#if APP
public Issue7621()
{
Device.SetFlags(new List<string> { CollectionView.CollectionViewExperimental });
InitializeComponent();
BindingContext = new ViewModel7621();
}
#endif
protected override void Init()
{
}
void ButtonClicked(object sender, EventArgs e)
{
var button = sender as Button;
var grid = button.Parent.Parent as Grid;
var collectionView = grid.Children[1] as CollectionView;
isMeasuringAllItems = !isMeasuringAllItems;
collectionView.ItemSizingStrategy = isMeasuringAllItems ? ItemSizingStrategy.MeasureAllItems : ItemSizingStrategy.MeasureFirstItem;
button.Text = isMeasuringAllItems ? "Switch to MeasureFirstItem" : "Switch to MeasureAllItems";
}
}
[Preserve(AllMembers = true)]
public class ViewModel7621
{
public ObservableCollection<Model7621> Items { get; set; }
public ViewModel7621()
{
var collection = new ObservableCollection<Model7621>();
Color[] _colors =
{
Color.Red,
Color.Blue,
Color.Green,
Color.Yellow
};
string[] _images =
{
"cover1.jpg",
"oasis.jpg",
"photo.jpg",
"Vegetables.jpg"
};
for (var i = 0; i < 30; i++)
{
collection.Add(new Model7621
{
BackgroundColor = _colors[i % 4],
Source = _images[i % 4]
});
}
Items = collection;
}
}
[Preserve(AllMembers = true)]
public class Model7621
{
public Color BackgroundColor { get; set; }
public string Source { get; set; }
}
}

Просмотреть файл

@ -19,6 +19,9 @@
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewHeaderFooterView.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewItemsUpdatingScrollMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3475.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue7621.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue6889.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue6945.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue7329.cs" />
@ -1381,6 +1384,9 @@
<Compile Update="C:\Users\hartez\Documents\Xamarin\Xamarin.Forms\Xamarin.Forms.Controls.Issues\Xamarin.Forms.Controls.Issues.Shared\Issue7519Xaml.xaml.cs">
<DependentUpon>Issue7519Xaml.xaml</DependentUpon>
</Compile>
<Compile Update="$(MSBuildThisFileDirectory)Issue7621.xaml.cs">
<DependentUpon>Issue7621.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue1455.xaml">
@ -1418,4 +1424,10 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue7621.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

Просмотреть файл

@ -12,8 +12,9 @@ namespace Xamarin.Forms.Platform.iOS
public override void ConstrainTo(CGSize constraint)
{
base.ConstrainTo(constraint);
ConstrainedDimension = constraint.Height;
Layout(constraint);
}
protected override (bool, Size) NeedsContentSizeUpdate(Size currentSize)

Просмотреть файл

@ -10,6 +10,8 @@ namespace Xamarin.Forms.Platform.iOS
{
public event EventHandler<EventArgs> ContentSizeChanged;
protected CGSize ConstrainedSize;
protected nfloat ConstrainedDimension;
DataTemplate _currentTemplate;
@ -25,9 +27,18 @@ namespace Xamarin.Forms.Platform.iOS
internal IVisualElementRenderer VisualElementRenderer { get; private set; }
public override void ConstrainTo(CGSize constraint)
{
ConstrainedSize = constraint;
}
public override void ConstrainTo(nfloat constant)
{
ConstrainedDimension = constant;
// Reset constrained size in case ItemSizingStrategy changes
// and we want to measure each item
ConstrainedSize = default(CGSize);
}
public override UICollectionViewLayoutAttributes PreferredLayoutAttributesFittingAttributes(
@ -35,8 +46,8 @@ namespace Xamarin.Forms.Platform.iOS
{
var preferredAttributes = base.PreferredLayoutAttributesFittingAttributes(layoutAttributes);
// Measure this cell (including the Forms element)
var size = Measure();
// Measure this cell (including the Forms element) if there is no constrained size
var size = ConstrainedSize == default(CGSize) ? Measure() : ConstrainedSize;
// Update the size of the root view to accommodate the Forms element
var nativeView = VisualElementRenderer.NativeView;

Просмотреть файл

@ -12,8 +12,9 @@ namespace Xamarin.Forms.Platform.iOS
public override void ConstrainTo(CGSize constraint)
{
base.ConstrainTo(constraint);
ConstrainedDimension = constraint.Width;
Layout(constraint);
}
protected override (bool, Size) NeedsContentSizeUpdate(Size currentSize)