diff options
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs | 149 |
1 files changed, 106 insertions, 43 deletions
diff --git a/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs index 3c235806..fd0f15f6 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs @@ -29,6 +29,7 @@ namespace Xamarin.Forms.Platform.iOS IListViewController Controller => Element; ITemplatedItemsView<Cell> TemplatedItemsView => Element; public override UIViewController ViewController => _tableViewController; + bool _disposed; public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) { @@ -90,28 +91,31 @@ namespace Xamarin.Forms.Platform.iOS } } + void DisposeSubviews(UIView view) + { + foreach (UIView subView in view.Subviews) + DisposeSubviews(subView); + + view.RemoveFromSuperview(); + view.Dispose(); + } + protected override void Dispose(bool disposing) { - // check inset tracker for null to - if (disposing && _insetTracker != null) - { - _insetTracker.Dispose(); - _insetTracker = null; + if (_disposed) + return; - var viewsToLookAt = new Stack<UIView>(Subviews); - while (viewsToLookAt.Count > 0) + if (disposing) + { + if (_insetTracker != null) { - var view = viewsToLookAt.Pop(); - var viewCellRenderer = view as ViewCellRenderer.ViewTableCell; - if (viewCellRenderer != null) - viewCellRenderer.Dispose(); - else - { - foreach (var child in view.Subviews) - viewsToLookAt.Push(child); - } + _insetTracker.Dispose(); + _insetTracker = null; } + foreach (UIView subview in Subviews) + DisposeSubviews(subview); + if (Element != null) { var templatedItems = TemplatedItemsView.TemplatedItems; @@ -119,27 +123,28 @@ namespace Xamarin.Forms.Platform.iOS templatedItems.GroupedCollectionChanged -= OnGroupedCollectionChanged; } + if (_dataSource != null) + { + _dataSource.Dispose(); + _dataSource = null; + } + if (_tableViewController != null) { _tableViewController.Dispose(); _tableViewController = null; } - } - if (disposing) - { if (_headerRenderer != null) { - var platform = _headerRenderer.Element.Platform as Platform; - if (platform != null) - platform.DisposeModelAndChildrenRenderers(_headerRenderer.Element); + var platform = _headerRenderer.Element?.Platform as Platform; + platform?.DisposeModelAndChildrenRenderers(_headerRenderer.Element); _headerRenderer = null; } if (_footerRenderer != null) { - var platform = _footerRenderer.Element.Platform as Platform; - if (platform != null) - platform.DisposeModelAndChildrenRenderers(_footerRenderer.Element); + var platform = _footerRenderer.Element?.Platform as Platform; + platform?.DisposeModelAndChildrenRenderers(_footerRenderer.Element); _footerRenderer = null; } @@ -154,6 +159,8 @@ namespace Xamarin.Forms.Platform.iOS Control?.TableFooterView?.Dispose(); } + _disposed = true; + base.Dispose(disposing); } @@ -602,6 +609,7 @@ namespace Xamarin.Forms.Platform.iOS internal class UnevenListViewDataSource : ListViewDataSource { IVisualElementRenderer _prototype; + bool _disposed; public UnevenListViewDataSource(ListView list, FormsUITableViewController uiTableViewController) : base(list, uiTableViewController) { @@ -661,27 +669,47 @@ namespace Xamarin.Forms.Platform.iOS { var target = viewCell.View; if (_prototype == null) - { _prototype = Platform.CreateRenderer(target); - Platform.SetRenderer(target, _prototype); - } else - { _prototype.SetElement(target); - Platform.SetRenderer(target, _prototype); - } + + Platform.SetRenderer(target, _prototype); var req = target.Measure(tableView.Frame.Width, double.PositiveInfinity, MeasureFlags.IncludeMargins); target.ClearValue(Platform.RendererProperty); - foreach (var descendant in target.Descendants()) + foreach (Element descendant in target.Descendants()) + { + IVisualElementRenderer renderer = Platform.GetRenderer(descendant as VisualElement); descendant.ClearValue(Platform.RendererProperty); + renderer?.Dispose(); + } return (nfloat)req.Request.Height; } + var renderHeight = cell.RenderHeight; return renderHeight > 0 ? (nfloat)renderHeight : DefaultRowHeight; } + + protected override void Dispose(bool disposing) + { + if (_disposed) + return; + + _disposed = true; + + if (disposing) + { + if (_prototype != null) + { + _prototype.Dispose(); + _prototype = null; + } + } + + base.Dispose(disposing); + } } internal class ListViewDataSource : UITableViewSource @@ -689,14 +717,15 @@ namespace Xamarin.Forms.Platform.iOS const int DefaultItemTemplateId = 1; static int s_dataTemplateIncrementer = 2; // lets start at not 0 because readonly nfloat _defaultSectionHeight; - readonly Dictionary<DataTemplate, int> _templateToId = new Dictionary<DataTemplate, int>(); - readonly UITableView _uiTableView; - readonly FormsUITableViewController _uiTableViewController; - protected readonly ListView List; + Dictionary<DataTemplate, int> _templateToId = new Dictionary<DataTemplate, int>(); + UITableView _uiTableView; + FormsUITableViewController _uiTableViewController; + protected ListView List; IListViewController Controller => List; protected ITemplatedItemsView<Cell> TemplatedItemsView => List; bool _isDragging; bool _selectionFromNative; + bool _disposed; public ListViewDataSource(ListViewDataSource source) { @@ -1016,6 +1045,29 @@ namespace Xamarin.Forms.Platform.iOS ((INotifyCollectionChanged)templatedList.ShortNames).CollectionChanged -= OnShortNamesCollectionChanged; } } + + protected override void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + if (List != null) + { + List.ItemSelected -= OnItemSelected; + List = null; + } + + _templateToId = null; + _uiTableView = null; + _uiTableViewController = null; + } + + _disposed = true; + + base.Dispose(disposing); + } } } @@ -1031,11 +1083,12 @@ namespace Xamarin.Forms.Platform.iOS internal class FormsUITableViewController : UITableViewController { - readonly ListView _list; + ListView _list; IListViewController Controller => _list; UIRefreshControl _refresh; bool _refreshAdded; + bool _disposed; public FormsUITableViewController(ListView element) { @@ -1117,15 +1170,25 @@ namespace Xamarin.Forms.Platform.iOS protected override void Dispose(bool disposing) { - base.Dispose(disposing); + if (_disposed) + return; - if (disposing && _refresh != null) + if (disposing) { - _refresh.ValueChanged -= OnRefreshingChanged; - _refresh.EndRefreshing(); - _refresh.Dispose(); - _refresh = null; + if (_refresh != null) + { + _refresh.ValueChanged -= OnRefreshingChanged; + _refresh.EndRefreshing(); + _refresh.Dispose(); + _refresh = null; + } + + _list = null; } + + _disposed = true; + + base.Dispose(disposing); } void CheckContentSize() |