Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ported pending fixes from Xamarin.Forms #5510

Merged
merged 5 commits into from
Mar 26, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ internal void Recycle()
RemoveView(Content.View);
}

Content?.Dispose();
Content = null;
_size = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,10 @@ void OnDataChanged()
// we need to reset the ListView's adapter to reflect the changes on page B
// If there header and footer are present at the reset time of the adapter
// they will be DOUBLE added to the ViewGround (the ListView) causing indexes to be off by one.

if (_realListView.IsDisposed())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid reset ListView adapter in TabbedPage if is already disposed
xamarin/Xamarin.Forms#14635

return;

_realListView.RemoveHeaderView(HeaderView);
_realListView.RemoveFooterView(FooterView);
_realListView.Adapter = _realListView.Adapter;
Expand Down
9 changes: 7 additions & 2 deletions src/Compatibility/Core/src/Android/VisualElementTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,13 @@ void UpdateScale()
VisualElement view = _renderer.Element;
AView aview = _renderer.View;

aview.ScaleX = (float)view.Scale * (float)view.ScaleX;
aview.ScaleY = (float)view.Scale * (float)view.ScaleY;
var scale = view.Scale;

if (double.IsNaN(scale))
return;

aview.ScaleX = (float)scale * (float)view.ScaleX;
aview.ScaleY = (float)scale * (float)view.ScaleY;
}

[PortHandler]
Expand Down
23 changes: 5 additions & 18 deletions src/Compatibility/Core/src/Windows/CellControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,17 +334,10 @@ void SetCell(object newContext)
// If there is a ListView, load the Cell content from the ItemTemplate.
// Otherwise, the given Cell is already a templated Cell from a TableView.
ListView lv = _listView.Value;

if (lv != null)
{
// 🚀 If there is an old cell, check if it was a group header
// we need this later to know whether we can recycle this cell
bool? wasGroupHeader = null;
var oldCell = Cell;
if (oldCell != null)
{
wasGroupHeader = oldCell.GetIsGroupHeader<ItemsView<Cell>, Cell>();
}

Cell oldCell = Cell;
bool isGroupHeader = IsGroupHeader;
DataTemplate template = isGroupHeader ? lv.GroupHeaderTemplate : lv.ItemTemplate;
object bindingContext = newContext;
Expand All @@ -362,15 +355,8 @@ void SetCell(object newContext)
sameTemplate = oldTemplate == template;
}
}
// 🚀 if there is no datatemplateselector, we now verify if the old cell
// was a groupheader and whether the new one is as well.
// Again, this is only to verify we can reuse this cell
else if (wasGroupHeader.HasValue)
{
sameTemplate = wasGroupHeader == isGroupHeader;
}

// reuse cell
// Reuse cell
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix ListView grouping not working on Windows
xamarin/Xamarin.Forms#14653

var canReuseCell = Cell != null && sameTemplate;

// 🚀 If we can reuse the cell, just reuse it...
Expand Down Expand Up @@ -407,7 +393,8 @@ void SetCell(object newContext)

if (Cell != cell)
Cell = cell;
// 🚀 even if the cell did not change, we **must** call SendDisappearing() and SendAppearing()

// 🚀 Even if the cell did not change, we **must** call SendDisappearing() and SendAppearing()
// because frameworks such as Reactive UI rely on this! (this.WhenActivated())
else if (Cell != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public sealed class FontImageSourceHandler : IImageSourceHandler, IIconElementHa
{
FontFamily = GetFontSource(fontsource),
FontSize = (float)fontsource.Size,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Center,
Options = CanvasDrawTextOptions.Default
};
Expand All @@ -51,9 +51,7 @@ public sealed class FontImageSourceHandler : IImageSourceHandler, IIconElementHa
var iconcolor = (fontsource.Color != null ? fontsource.Color : Colors.White).ToWindowsColor();

// offset by 1 as we added a 1 inset
var x = (float)layout.DrawBounds.X * -1;

ds.DrawTextLayout(layout, x, 1f, iconcolor);
ds.DrawTextLayout(layout, 1f, 1f, iconcolor);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix FontIcons alignment
xamarin/Xamarin.Forms#15047

}

return Task.FromResult((UI.Xaml.Media.ImageSource)imageSource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public abstract class ItemsViewController<TItemsView> : UICollectionViewControll
public TItemsView ItemsView { get; }
protected ItemsViewLayout ItemsViewLayout { get; set; }
bool _initialized;
bool _isEmpty;
bool _isEmpty = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prevent CollectionView.EmptyView from showing up while it shouldn't on iOS
xamarin/Xamarin.Forms#15122

bool _emptyViewDisplayed;
bool _disposed;

Expand Down Expand Up @@ -212,6 +212,7 @@ public virtual void UpdateItemsSource()
{
_measurementCells.Clear();
ItemsViewLayout?.ClearCellSizeCache();
ItemsSource?.Dispose();
ItemsSource = CreateItemsViewSource();
CollectionView.ReloadData();
CollectionView.CollectionViewLayout.InvalidateLayout();
Expand Down Expand Up @@ -470,7 +471,14 @@ void AlignEmptyView()
return;
}

if (CollectionView.EffectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.RightToLeft)
bool isRtl;

if (PlatformVersion.IsAtLeast(10))
isRtl = CollectionView.EffectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.RightToLeft;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix CollectionView crash in iOS < 10
xamarin/Xamarin.Forms#14925

else
isRtl = CollectionView.SemanticContentAttribute == UISemanticContentAttribute.ForceRightToLeft;

if (isRtl)
{
if (_emptyUIView.Transform.A == -1)
{
Expand Down Expand Up @@ -621,6 +629,7 @@ internal protected virtual void UpdateVisibility()
{
if (CollectionView.Hidden)
{
CollectionView.ReloadData();
CollectionView.Hidden = false;
Layout.InvalidateLayout();
CollectionView.LayoutIfNeeded();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ void CollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
void CollectionChanged(NotifyCollectionChangedEventArgs args)
{
// Force UICollectionView to get the internal accounting straight
CollectionView.NumberOfItemsInSection(_section);
if (!CollectionView.Hidden)
CollectionView.NumberOfItemsInSection(_section);

switch (args.Action)
{
Expand Down
23 changes: 15 additions & 8 deletions src/Compatibility/Core/src/iOS/CollectionView/TemplatedCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ void SetRenderer(IVisualElementRenderer renderer)

InitializeContentConstraints(nativeView);

UpdateVisualStates();

renderer.Element.MeasureInvalidated += MeasureInvalidated;
}

Expand Down Expand Up @@ -236,14 +238,7 @@ public override bool Selected
{
base.Selected = value;

var element = VisualElementRenderer?.Element;

if (element != null)
{
VisualStateManager.GoToState(element, value
? VisualStateManager.CommonStates.Selected
: VisualStateManager.CommonStates.Normal);
}
UpdateVisualStates();
}
}

Expand Down Expand Up @@ -293,5 +288,17 @@ bool SizesAreSame(CGSize preferredSize, Size elementSize)

return true;
}

void UpdateVisualStates()
{
var element = VisualElementRenderer?.Element;

if (element != null)
{
VisualStateManager.GoToState(element, Selected
? VisualStateManager.CommonStates.Selected
: VisualStateManager.CommonStates.Normal);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -52,9 +53,9 @@ public void AddFrameData(int index, CGImageSource imageSource)
using (var delayTimeValue = gifImageProperties?.ValueForKey(ImageIO.CGImageProperties.GIFDelayTime))
{
if (unclampedDelayTimeValue != null)
double.TryParse(unclampedDelayTimeValue.ToString(), out delayTime);
double.TryParse(unclampedDelayTimeValue.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out delayTime);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix issue with gifs and differents DefaultThreadCurrentCulture on iOS
xamarin/Xamarin.Forms#14698

else if (delayTimeValue != null)
double.TryParse(delayTimeValue.ToString(), out delayTime);
double.TryParse(delayTimeValue.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out delayTime);

// Frame delay compability adjustment.
if (delayTime <= 0.02f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
}
_tableViewController = new FormsUITableViewController(e.NewElement, _usingLargeTitles);
SetNativeControl(_tableViewController.TableView);

if (Forms.IsiOS15OrNewer)
_tableViewController.TableView.SectionHeaderTopPadding = new nfloat(0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix issue with ListView wrong top padding in iOS 15
xamarin/Xamarin.Forms#14671


_backgroundUIView = _tableViewController.TableView.BackgroundView;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,10 @@ void OnDataChanged()
// we need to reset the ListView's adapter to reflect the changes on page B
// If there header and footer are present at the reset time of the adapter
// they will be DOUBLE added to the ViewGround (the ListView) causing indexes to be off by one.

if (_realListView.IsDisposed())
return;

_realListView.RemoveHeaderView(HeaderView);
_realListView.RemoveFooterView(FooterView);
_realListView.Adapter = _realListView.Adapter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,14 +440,27 @@ void UpdateIsRefreshing(bool isInitialValue = false)
});
}
else
_refresh.Refreshing = isRefreshing;
_refresh.Refreshing = isRefreshing;

// Allow to disable SwipeToRefresh layout AFTER refresh is done
UpdateIsSwipeToRefreshEnabled();
}
}

void UpdateIsSwipeToRefreshEnabled()
{
if (_refresh != null)
_refresh.Enabled = Element.IsPullToRefreshEnabled && (Element as IListViewController).RefreshAllowed;
{
var isEnabled = Element.IsPullToRefreshEnabled && (Element as IListViewController).RefreshAllowed;
_refresh.Post(() =>
{
// NOTE: only disable while NOT refreshing, otherwise Command bindings CanExecute behavior will effectively
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid that disabling ListView RefreshAllowed cancels refresh indicator on Android
xamarin/Xamarin.Forms#14816

// cancel refresh animation. If not possible right now we will be called by UpdateIsRefreshing().
// For details see https://github.com/xamarin/Xamarin.Forms/issues/8384
if (isEnabled || !_refresh.Refreshing)
_refresh.Enabled = isEnabled;
});
}
}

void UpdateFastScrollEnabled()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,17 +330,10 @@ void SetCell(object newContext)
// If there is a ListView, load the Cell content from the ItemTemplate.
// Otherwise, the given Cell is already a templated Cell from a TableView.
ListView lv = _listView.Value;

if (lv != null)
{
// 🚀 If there is an old cell, check if it was a group header
// we need this later to know whether we can recycle this cell
bool? wasGroupHeader = null;
var oldCell = Cell;
if (oldCell != null)
{
wasGroupHeader = oldCell.GetIsGroupHeader<ItemsView<Cell>, Cell>();
}

Cell oldCell = Cell;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool isGroupHeader = IsGroupHeader;
DataTemplate template = isGroupHeader ? lv.GroupHeaderTemplate : lv.ItemTemplate;
object bindingContext = newContext;
Expand All @@ -358,15 +351,8 @@ void SetCell(object newContext)
sameTemplate = oldTemplate == template;
}
}
// 🚀 if there is no datatemplateselector, we now verify if the old cell
// was a groupheader and whether the new one is as well.
// Again, this is only to verify we can reuse this cell
else if (wasGroupHeader.HasValue)
{
sameTemplate = wasGroupHeader == isGroupHeader;
}

// reuse cell
// Reuse cell
var canReuseCell = Cell != null && sameTemplate;

// 🚀 If we can reuse the cell, just reuse it...
Expand Down Expand Up @@ -403,7 +389,8 @@ void SetCell(object newContext)

if (Cell != cell)
Cell = cell;
// 🚀 even if the cell did not change, we **must** call SendDisappearing() and SendAppearing()

// 🚀 Even if the cell did not change, we **must** call SendDisappearing() and SendAppearing()
// because frameworks such as Reactive UI rely on this! (this.WhenActivated())
else if (Cell != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
}
_tableViewController = new FormsUITableViewController(e.NewElement, _usingLargeTitles);
SetNativeControl(_tableViewController.TableView);

if (PlatformVersion.IsAtLeast(15))
_tableViewController.TableView.SectionHeaderTopPadding = new nfloat(0);

_backgroundUIView = _tableViewController.TableView.BackgroundView;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ void Destroy()

if (_root is ViewGroup vg)
vg.RemoveView(_shellPageContainer);

_shellPageContainer.Dispose();
}

_root?.Dispose();
Expand All @@ -186,6 +188,7 @@ void Destroy()
_root = null;
_viewhandler = null;
_shellContent = null;
_shellPageContainer = null;
}

protected override void Dispose(bool disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,10 @@ protected override void Dispose(bool disposing)
_currentMenuItems?.Clear();
_currentToolbarItems?.Clear();

_drawerLayout.RemoveDrawerListener(_drawerToggle);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix content pages not Garbage collected
xamarin/Xamarin.Forms#14717

_drawerToggle?.Dispose();

_toolbar.RemoveAllViews();
}

_currentMenuItems = null;
Expand Down
12 changes: 10 additions & 2 deletions src/Controls/src/Core/Handlers/Items/iOS/ItemsViewController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public abstract class ItemsViewController<TItemsView> : UICollectionViewControll
public TItemsView ItemsView { get; }
protected ItemsViewLayout ItemsViewLayout { get; set; }
bool _initialized;
bool _isEmpty;
bool _isEmpty = true;
bool _emptyViewDisplayed;
bool _disposed;

Expand Down Expand Up @@ -211,6 +211,7 @@ public virtual void UpdateItemsSource()
{
_measurementCells.Clear();
ItemsViewLayout?.ClearCellSizeCache();
ItemsSource?.Dispose();
ItemsSource = CreateItemsViewSource();
CollectionView.ReloadData();
CollectionView.CollectionViewLayout.InvalidateLayout();
Expand Down Expand Up @@ -472,7 +473,14 @@ void AlignEmptyView()
return;
}

if (CollectionView.EffectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.RightToLeft)
bool isRtl;

if (PlatformVersion.IsAtLeast(10))
isRtl = CollectionView.EffectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.RightToLeft;
else
isRtl = CollectionView.SemanticContentAttribute == UISemanticContentAttribute.ForceRightToLeft;

if (isRtl)
{
if (_emptyUIView.Transform.A == -1)
{
Expand Down
Loading