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

Commit

Permalink
Remove unnecessary UpdateConstraints calls when rotating (#12728)
Browse files Browse the repository at this point in the history
* Remove unnecessary extra UpdateConstraints calls when rotating
Fixes #12193

* Restore correct height measurement

* Scroll to current position when Carousel appears

* Fix position setting

* Validate scrollto position on CarouselView before attempting to scroll
  • Loading branch information
hartez authored Nov 11, 2020
1 parent 938700b commit b551dd9
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

#if UITEST
using Xamarin.Forms.Core.UITests;
using Xamarin.UITest;
using NUnit.Framework;
#endif

namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.CarouselView)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 12193, "[Bug] CarouselView content disappears after 2 rotations if TextType=Html is used",
PlatformAffected.iOS)]
public class Issue12193 : TestContentPage
{
public const string HTML = "HTML";

protected override void Init()
{
#if APP
Title = "CarouselView HTML Label";

var instructions = new Label { Text = $"Rotate the device, then rotate it back 3 times. If the label \"{HTML}\" disappears, this test has failed." };

var source = new List<string>();
for (int n = 0; n < 10; n++)
{
source.Add($"Item: {n}");
}

var template = new DataTemplate(() =>
{
var label = new Label
{
TextType = TextType.Html,
Text = $"<p style='background-color:red;'>{HTML}</p>",
AutomationId = HTML
};
return label;
});

var cv = new CarouselView()
{
ItemsSource = source,
ItemTemplate = template,
Loop = false
};

var layout = new StackLayout();

layout.Children.Add(instructions);
layout.Children.Add(cv);

Content = layout;
#endif
}


#if UITEST
[Test]
public async Task RotatingCarouselViewHTMLShouldNotDisappear()
{
int delay = 3000;

RunningApp.SetOrientationPortrait();
await Task.Delay(delay);

RunningApp.SetOrientationLandscape();
await Task.Delay(delay);

RunningApp.SetOrientationPortrait();
await Task.Delay(delay);

RunningApp.SetOrientationLandscape();
await Task.Delay(delay);

RunningApp.SetOrientationPortrait();
await Task.Delay(delay);

RunningApp.WaitForElement(HTML);
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue10897.xaml.cs">
<DependentUpon>Issue10897.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue12193.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12320.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12153.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue10324.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,28 @@ namespace Xamarin.Forms.Platform.iOS
public class CarouselTemplatedCell : TemplatedCell
{
public static NSString ReuseId = new NSString("Xamarin.Forms.Platform.iOS.CarouselTemplatedCell");
CGSize _constraint;

[Export("initWithFrame:")]
[Internals.Preserve(Conditional = true)]
protected CarouselTemplatedCell(CGRect frame) : base(frame)
{ }
{
}

public override void ConstrainTo(nfloat constant)
{

}
CGSize _constrain;

public override void ConstrainTo(CGSize constraint)
{
_constrain = constraint;
Layout(constraint);
ClearConstraints();

_constraint = constraint;
}

public override CGSize Measure()
{
return new CGSize(_constrain.Width,_constrain.Height);
return new CGSize(_constraint.Width, _constraint.Height);
}

protected override (bool, Size) NeedsContentSizeUpdate(Size currentSize)
Expand Down
40 changes: 15 additions & 25 deletions Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using CoreGraphics;
using Foundation;
Expand All @@ -15,7 +16,6 @@ public class CarouselViewController : ItemsViewController<CarouselView>

CarouselViewLoopManager _carouselViewLoopManager;
bool _initialPositionSet;
bool _viewInitialized;
bool _updatingScrollOffset;
List<View> _oldViews;
int _gotoPosition = -1;
Expand Down Expand Up @@ -64,31 +64,33 @@ public override void ViewDidLoad()
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
if (!_viewInitialized)
{
_viewInitialized = true;
_size = CollectionView.Bounds.Size;
}

UpdateVisualStates();
}

public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
if (CollectionView.Bounds.Size != _size)
{
_size = CollectionView.Bounds.Size;
BoundsSizeChanged();
}

if (Carousel?.Loop == true && _carouselViewLoopManager != null)
{
_updatingScrollOffset = true;
_carouselViewLoopManager.CenterIfNeeded(CollectionView, IsHorizontal);
_updatingScrollOffset = false;
}

UpdateInitialPosition();

if (CollectionView.Bounds.Size != _size)
{
_size = CollectionView.Bounds.Size;
BoundsSizeChanged();
}
}

void BoundsSizeChanged()
{
//if the size changed center the item
Carousel.ScrollTo(Carousel.Position, position: Xamarin.Forms.ScrollToPosition.Center, animate: false);
}

public override void DraggingStarted(UIScrollView scrollView)
Expand All @@ -105,7 +107,7 @@ public override void UpdateItemsSource()
{
UnsubscribeCollectionItemsSourceChanged(ItemsSource);
base.UpdateItemsSource();
//we don't need to Subscribe becasse base calls CreateItemsViewSource
//we don't need to Subscribe because base calls CreateItemsViewSource
_carouselViewLoopManager?.SetItemsSource(LoopItemsSource);
_initialPositionSet = false;
UpdateInitialPosition();
Expand Down Expand Up @@ -137,18 +139,6 @@ protected override IItemsViewSource CreateItemsViewSource()
return itemsSource;
}

protected void BoundsSizeChanged()
{
//we might be rotating our phone
ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size);

//We call ReloadData so our VisibleCells also update their size
CollectionView.ReloadData();

//if the size changed center the item
Carousel.ScrollTo(Carousel.Position, position: Xamarin.Forms.ScrollToPosition.Center, animate: false);
}

internal void TearDown()
{
Carousel.PropertyChanged -= CarouselViewPropertyChanged;
Expand Down
11 changes: 0 additions & 11 deletions Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ public CarouselViewLayout(ItemsLayout itemsLayout, CarouselView carouselView) :
_itemsLayout = itemsLayout;
}

public override bool ShouldInvalidateLayoutForBoundsChange(CGRect newBounds)
{
return false;
}

public override void ConstrainTo(CGSize size)
{
//TODO: Should we scale the items
Expand All @@ -37,12 +32,6 @@ public override void ConstrainTo(CGSize size)
}
}

internal override void UpdateConstraints(CGSize size)
{
ConstrainTo(size);
UpdateCellConstraints();
}

public override nfloat GetMinimumInteritemSpacingForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section)
{
if (_itemsLayout is LinearItemsLayout linearItemsLayout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ protected override void ScrollToRequested(object sender, ScrollToRequestEventArg
if (Carousel?.Loop == true)
{
var goToIndexPath = Controller.GetScrollToIndexPath(args.Index);

if (!IsIndexPathValid(goToIndexPath))
{
return;
}

Controller.CollectionView.ScrollToItem(goToIndexPath,
args.ScrollToPosition.ToCollectionViewScrollPosition(_layout.ScrollDirection),
args.IsAnimated);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,5 @@ void UpdateEmptyViewVisibility(bool isEmpty)
_emptyViewDisplayed = false;
}
}

}
}
10 changes: 2 additions & 8 deletions Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -527,15 +527,9 @@ public override bool ShouldInvalidateLayoutForBoundsChange(CGRect newBounds)
return base.ShouldInvalidateLayoutForBoundsChange(newBounds);
}

return true;
}
UpdateConstraints(CollectionView.AdjustedContentInset.InsetRect(newBounds).Size);

public override void InvalidateLayout()
{
if (CollectionView != null && CollectionView.Frame != null) {
UpdateConstraints(CollectionView.Frame.Size);
}
base.InvalidateLayout();
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
}

bool IsIndexPathValid(NSIndexPath indexPath)
protected bool IsIndexPathValid(NSIndexPath indexPath)
{
if (indexPath.Item < 0 || indexPath.Section < 0)
{
Expand Down

0 comments on commit b551dd9

Please sign in to comment.