diff options
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Cells')
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs | 77 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/CellTableViewCell.cs | 96 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/EntryCellRenderer.cs | 186 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/ImageCellRenderer.cs | 70 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/SwitchCellRenderer.cs | 94 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/TextCellRenderer.cs | 73 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs | 176 |
7 files changed, 772 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs new file mode 100644 index 00000000..c01a7774 --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs @@ -0,0 +1,77 @@ +using System; +#if __UNIFIED__ +using UIKit; +using Foundation; + +#else +using MonoTouch.UIKit; +using MonoTouch.Foundation; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class CellRenderer : IRegisterable + { + static readonly BindableProperty RealCellProperty = BindableProperty.CreateAttached("RealCell", typeof(UITableViewCell), typeof(Cell), null); + + EventHandler _onForceUpdateSizeRequested; + + public virtual UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) + { + var tvc = reusableCell as CellTableViewCell ?? new CellTableViewCell(UITableViewCellStyle.Default, item.GetType().FullName); + + tvc.Cell = item; + + WireUpForceUpdateSizeRequested(item, tvc, tv); + + tvc.TextLabel.Text = item.ToString(); + + UpdateBackground(tvc, item); + return tvc; + } + + protected void UpdateBackground(UITableViewCell tableViewCell, Cell cell) + { + if (TemplatedItemsList<ItemsView<Cell>, Cell>.GetIsGroupHeader(cell)) + { + if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0)) + tableViewCell.BackgroundColor = new UIColor(247f / 255f, 247f / 255f, 247f / 255f, 1); + } + else + { + // Must be set to a solid color or blending issues will occur + var bgColor = UIColor.White; + + var element = cell.RealParent as VisualElement; + if (element != null) + bgColor = element.BackgroundColor == Color.Default ? bgColor : element.BackgroundColor.ToUIColor(); + + tableViewCell.BackgroundColor = bgColor; + } + } + + protected void WireUpForceUpdateSizeRequested(Cell cell, UITableViewCell nativeCell, UITableView tableView) + { + cell.ForceUpdateSizeRequested -= _onForceUpdateSizeRequested; + + _onForceUpdateSizeRequested = delegate + { + var index = tableView.IndexPathForCell(nativeCell); + if (index != null) + tableView.ReloadRows(new[] { index }, UITableViewRowAnimation.None); + }; + + cell.ForceUpdateSizeRequested += _onForceUpdateSizeRequested; + } + + internal static UITableViewCell GetRealCell(BindableObject cell) + { + return (UITableViewCell)cell.GetValue(RealCellProperty); + } + + internal static void SetRealCell(BindableObject cell, UITableViewCell renderer) + { + cell.SetValue(RealCellProperty, renderer); + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Platform.iOS/Cells/CellTableViewCell.cs b/Xamarin.Forms.Platform.iOS/Cells/CellTableViewCell.cs new file mode 100644 index 00000000..a9265868 --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Cells/CellTableViewCell.cs @@ -0,0 +1,96 @@ +using System; +using System.ComponentModel; +#if __UNIFIED__ +using UIKit; + +#else +using MonoTouch.UIKit; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class CellTableViewCell : UITableViewCell, INativeElementView + { + Cell _cell; + + public Action<object, PropertyChangedEventArgs> PropertyChanged; + + public CellTableViewCell(UITableViewCellStyle style, string key) : base(style, key) + { + } + + public Cell Cell + { + get { return _cell; } + set + { + if (_cell == value) + return; + + if (_cell != null) + Device.BeginInvokeOnMainThread(_cell.SendDisappearing); + _cell = value; + if (_cell != null) + Device.BeginInvokeOnMainThread(_cell.SendAppearing); + } + } + + public Element Element => Cell; + + public void HandlePropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + } + + internal static UITableViewCell GetNativeCell(UITableView tableView, Cell cell, bool recycleCells = false, string templateId = "") + { + var id = cell.GetType().FullName; + + var renderer = (CellRenderer)Registrar.Registered.GetHandler(cell.GetType()); + + ContextActionsCell contextCell = null; + UITableViewCell reusableCell = null; + if (cell.HasContextActions || recycleCells) + { + contextCell = (ContextActionsCell)tableView.DequeueReusableCell(ContextActionsCell.Key + templateId); + if (contextCell == null) + { + contextCell = new ContextActionsCell(templateId); + reusableCell = tableView.DequeueReusableCell(id); + } + else + { + contextCell.Close(); + reusableCell = contextCell.ContentCell; + + if (reusableCell.ReuseIdentifier.ToString() != id) + reusableCell = null; + } + } + else + reusableCell = tableView.DequeueReusableCell(id); + + var nativeCell = renderer.GetCell(cell, reusableCell, tableView); + + var cellWithContent = nativeCell; + + // Sometimes iOS for returns a dequeued cell whose Layer is hidden. + // This prevents it from showing up, so lets turn it back on! + if (cellWithContent.Layer.Hidden) + cellWithContent.Layer.Hidden = false; + + if (contextCell != null) + { + contextCell.Update(tableView, cell, nativeCell); + nativeCell = contextCell; + } + + // Because the layer was hidden we need to layout the cell by hand + if (cellWithContent != null) + cellWithContent.LayoutSubviews(); + + return nativeCell; + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Platform.iOS/Cells/EntryCellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/EntryCellRenderer.cs new file mode 100644 index 00000000..1af49b4a --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Cells/EntryCellRenderer.cs @@ -0,0 +1,186 @@ +using System; +using System.ComponentModel; +using System.Drawing; +#if __UNIFIED__ +using UIKit; +#else +using MonoTouch.UIKit; +#endif +#if __UNIFIED__ +using RectangleF = CoreGraphics.CGRect; +using SizeF = CoreGraphics.CGSize; +using PointF = CoreGraphics.CGPoint; + +#else +using nfloat=System.Single; +using nint=System.Int32; +using nuint=System.UInt32; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class EntryCellRenderer : CellRenderer + { + static readonly Color DefaultTextColor = Color.Black; + + public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) + { + var entryCell = (EntryCell)item; + + var tvc = reusableCell as EntryCellTableViewCell; + if (tvc == null) + tvc = new EntryCellTableViewCell(item.GetType().FullName); + else + { + tvc.Cell.PropertyChanged -= OnCellPropertyChanged; + tvc.TextFieldTextChanged -= OnTextFieldTextChanged; + tvc.KeyboardDoneButtonPressed -= OnKeyBoardDoneButtonPressed; + } + + SetRealCell(item, tvc); + + tvc.Cell = item; + tvc.Cell.PropertyChanged += OnCellPropertyChanged; + tvc.TextFieldTextChanged += OnTextFieldTextChanged; + tvc.KeyboardDoneButtonPressed += OnKeyBoardDoneButtonPressed; + + WireUpForceUpdateSizeRequested(item, tvc, tv); + + UpdateBackground(tvc, entryCell); + UpdateLabel(tvc, entryCell); + UpdateText(tvc, entryCell); + UpdateKeyboard(tvc, entryCell); + UpdatePlaceholder(tvc, entryCell); + UpdateLabelColor(tvc, entryCell); + UpdateHorizontalTextAlignment(tvc, entryCell); + UpdateIsEnabled(tvc, entryCell); + + return tvc; + } + + static void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e) + { + var entryCell = (EntryCell)sender; + var realCell = (EntryCellTableViewCell)GetRealCell(entryCell); + + if (e.PropertyName == EntryCell.LabelProperty.PropertyName) + UpdateLabel(realCell, entryCell); + else if (e.PropertyName == EntryCell.TextProperty.PropertyName) + UpdateText(realCell, entryCell); + else if (e.PropertyName == EntryCell.PlaceholderProperty.PropertyName) + UpdatePlaceholder(realCell, entryCell); + else if (e.PropertyName == EntryCell.KeyboardProperty.PropertyName) + UpdateKeyboard(realCell, entryCell); + else if (e.PropertyName == EntryCell.LabelColorProperty.PropertyName) + UpdateLabelColor(realCell, entryCell); + else if (e.PropertyName == EntryCell.HorizontalTextAlignmentProperty.PropertyName) + UpdateHorizontalTextAlignment(realCell, entryCell); + else if (e.PropertyName == Cell.IsEnabledProperty.PropertyName) + UpdateIsEnabled(realCell, entryCell); + } + + static void OnKeyBoardDoneButtonPressed(object sender, EventArgs e) + { + var cell = (EntryCellTableViewCell)sender; + var model = (EntryCell)cell.Cell; + + model.SendCompleted(); + } + + static void OnTextFieldTextChanged(object sender, EventArgs eventArgs) + { + var cell = (EntryCellTableViewCell)sender; + var model = (EntryCell)cell.Cell; + + model.Text = cell.TextField.Text; + } + + static void UpdateHorizontalTextAlignment(EntryCellTableViewCell cell, EntryCell entryCell) + { + cell.TextField.TextAlignment = entryCell.HorizontalTextAlignment.ToNativeTextAlignment(); + } + + static void UpdateIsEnabled(EntryCellTableViewCell cell, EntryCell entryCell) + { + cell.UserInteractionEnabled = entryCell.IsEnabled; + cell.TextLabel.Enabled = entryCell.IsEnabled; + cell.DetailTextLabel.Enabled = entryCell.IsEnabled; + cell.TextField.Enabled = entryCell.IsEnabled; + } + + static void UpdateKeyboard(EntryCellTableViewCell cell, EntryCell entryCell) + { + cell.TextField.ApplyKeyboard(entryCell.Keyboard); + } + + static void UpdateLabel(EntryCellTableViewCell cell, EntryCell entryCell) + { + cell.TextLabel.Text = entryCell.Label; + } + + static void UpdateLabelColor(EntryCellTableViewCell cell, EntryCell entryCell) + { + cell.TextLabel.TextColor = entryCell.LabelColor.ToUIColor(DefaultTextColor); + } + + static void UpdatePlaceholder(EntryCellTableViewCell cell, EntryCell entryCell) + { + cell.TextField.Placeholder = entryCell.Placeholder; + } + + static void UpdateText(EntryCellTableViewCell cell, EntryCell entryCell) + { + if (cell.TextField.Text == entryCell.Text) + return; + // double sets side effect on iOS, YAY + cell.TextField.Text = entryCell.Text; + } + + class EntryCellTableViewCell : CellTableViewCell + { + public EntryCellTableViewCell(string cellName) : base(UITableViewCellStyle.Value1, cellName) + { + TextField = new UITextField(new RectangleF(0, 0, 100, 30)) { BorderStyle = UITextBorderStyle.None }; + + TextField.EditingChanged += TextFieldOnEditingChanged; + TextField.ShouldReturn = OnShouldReturn; + + ContentView.AddSubview(TextField); + } + + public UITextField TextField { get; } + + public event EventHandler KeyboardDoneButtonPressed; + + public override void LayoutSubviews() + { + base.LayoutSubviews(); + + // simple algorithm to generally line up entries + var start = (nfloat)Math.Round(Math.Max(Frame.Width * 0.3, TextLabel.Frame.Right + 10)); + TextField.Frame = new RectangleF(start, (Frame.Height - 30) / 2, Frame.Width - TextLabel.Frame.Left - start, 30); + // Centers TextField Content (iOS6) + TextField.VerticalAlignment = UIControlContentVerticalAlignment.Center; + } + + public event EventHandler TextFieldTextChanged; + + bool OnShouldReturn(UITextField view) + { + var handler = KeyboardDoneButtonPressed; + if (handler != null) + handler(this, EventArgs.Empty); + + TextField.ResignFirstResponder(); + return true; + } + + void TextFieldOnEditingChanged(object sender, EventArgs eventArgs) + { + var handler = TextFieldTextChanged; + if (handler != null) + handler(this, EventArgs.Empty); + } + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Platform.iOS/Cells/ImageCellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/ImageCellRenderer.cs new file mode 100644 index 00000000..ade59e82 --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Cells/ImageCellRenderer.cs @@ -0,0 +1,70 @@ +using System.ComponentModel; +using System.Threading.Tasks; +#if __UNIFIED__ +using UIKit; +using Foundation; + +#else +using MonoTouch.UIKit; +using MonoTouch.Foundation; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class ImageCellRenderer : TextCellRenderer + { + public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) + { + var result = (CellTableViewCell)base.GetCell(item, reusableCell, tv); + + var imageCell = (ImageCell)item; + + WireUpForceUpdateSizeRequested(item, result, tv); + + SetImage(imageCell, result); + + return result; + } + + protected override void HandlePropertyChanged(object sender, PropertyChangedEventArgs args) + { + var tvc = (CellTableViewCell)sender; + var imageCell = (ImageCell)tvc.Cell; + + base.HandlePropertyChanged(sender, args); + + if (args.PropertyName == ImageCell.ImageSourceProperty.PropertyName) + SetImage(imageCell, tvc); + } + + async void SetImage(ImageCell cell, CellTableViewCell target) + { + var source = cell.ImageSource; + + target.ImageView.Image = null; + + IImageSourceHandler handler; + + if (source != null && (handler = Registrar.Registered.GetHandler<IImageSourceHandler>(source.GetType())) != null) + { + UIImage uiimage; + try + { + uiimage = await handler.LoadImageAsync(source).ConfigureAwait(false); + } + catch (TaskCanceledException) + { + uiimage = null; + } + + NSRunLoop.Main.BeginInvokeOnMainThread(() => + { + target.ImageView.Image = uiimage; + target.SetNeedsLayout(); + }); + } + else + target.ImageView.Image = null; + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Platform.iOS/Cells/SwitchCellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/SwitchCellRenderer.cs new file mode 100644 index 00000000..ed7ddc10 --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Cells/SwitchCellRenderer.cs @@ -0,0 +1,94 @@ +using System; +using System.ComponentModel; +using System.Drawing; +#if __UNIFIED__ +using UIKit; + +#else +using MonoTouch.UIKit; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class SwitchCellRenderer : CellRenderer + { + const string CellName = "Xamarin.SwitchCell"; + + public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) + { + var tvc = reusableCell as CellTableViewCell; + UISwitch uiSwitch = null; + if (tvc == null) + tvc = new CellTableViewCell(UITableViewCellStyle.Value1, CellName); + else + { + uiSwitch = tvc.AccessoryView as UISwitch; + tvc.Cell.PropertyChanged -= OnCellPropertyChanged; + } + + SetRealCell(item, tvc); + + if (uiSwitch == null) + { + uiSwitch = new UISwitch(new RectangleF()); + uiSwitch.ValueChanged += OnSwitchValueChanged; + tvc.AccessoryView = uiSwitch; + } + + var boolCell = (SwitchCell)item; + + tvc.Cell = item; + tvc.Cell.PropertyChanged += OnCellPropertyChanged; + tvc.AccessoryView = uiSwitch; + tvc.TextLabel.Text = boolCell.Text; + + uiSwitch.On = boolCell.On; + + WireUpForceUpdateSizeRequested(item, tvc, tv); + + UpdateBackground(tvc, item); + UpdateIsEnabled(tvc, boolCell); + + return tvc; + } + + void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e) + { + var boolCell = (SwitchCell)sender; + var realCell = (CellTableViewCell)GetRealCell(boolCell); + + if (e.PropertyName == SwitchCell.OnProperty.PropertyName) + ((UISwitch)realCell.AccessoryView).SetState(boolCell.On, true); + else if (e.PropertyName == SwitchCell.TextProperty.PropertyName) + realCell.TextLabel.Text = boolCell.Text; + else if (e.PropertyName == Cell.IsEnabledProperty.PropertyName) + UpdateIsEnabled(realCell, boolCell); + } + + void OnSwitchValueChanged(object sender, EventArgs eventArgs) + { + var view = (UIView)sender; + var sw = (UISwitch)view; + + CellTableViewCell realCell = null; + while (view.Superview != null && realCell == null) + { + view = view.Superview; + realCell = view as CellTableViewCell; + } + + if (realCell != null) + ((SwitchCell)realCell.Cell).On = sw.On; + } + + void UpdateIsEnabled(CellTableViewCell cell, SwitchCell switchCell) + { + cell.UserInteractionEnabled = switchCell.IsEnabled; + cell.TextLabel.Enabled = switchCell.IsEnabled; + cell.DetailTextLabel.Enabled = switchCell.IsEnabled; + var uiSwitch = cell.AccessoryView as UISwitch; + if (uiSwitch != null) + uiSwitch.Enabled = switchCell.IsEnabled; + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Platform.iOS/Cells/TextCellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/TextCellRenderer.cs new file mode 100644 index 00000000..41c43341 --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Cells/TextCellRenderer.cs @@ -0,0 +1,73 @@ +using System.ComponentModel; +#if __UNIFIED__ +using UIKit; + +#else +using MonoTouch.UIKit; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class TextCellRenderer : CellRenderer + { + static readonly Color DefaultDetailColor = new Color(.32, .4, .57); + static readonly Color DefaultTextColor = Color.Black; + + public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) + { + var textCell = (TextCell)item; + + var tvc = reusableCell as CellTableViewCell; + if (tvc == null) + tvc = new CellTableViewCell(UITableViewCellStyle.Subtitle, item.GetType().FullName); + else + tvc.Cell.PropertyChanged -= tvc.HandlePropertyChanged; + + tvc.Cell = textCell; + textCell.PropertyChanged += tvc.HandlePropertyChanged; + tvc.PropertyChanged = HandlePropertyChanged; + + tvc.TextLabel.Text = textCell.Text; + tvc.DetailTextLabel.Text = textCell.Detail; + tvc.TextLabel.TextColor = textCell.TextColor.ToUIColor(DefaultTextColor); + tvc.DetailTextLabel.TextColor = textCell.DetailColor.ToUIColor(DefaultDetailColor); + + WireUpForceUpdateSizeRequested(item, tvc, tv); + + UpdateIsEnabled(tvc, textCell); + + UpdateBackground(tvc, item); + + return tvc; + } + + protected virtual void HandlePropertyChanged(object sender, PropertyChangedEventArgs args) + { + var tvc = (CellTableViewCell)sender; + var textCell = (TextCell)tvc.Cell; + if (args.PropertyName == TextCell.TextProperty.PropertyName) + { + tvc.TextLabel.Text = ((TextCell)tvc.Cell).Text; + tvc.TextLabel.SizeToFit(); + } + else if (args.PropertyName == TextCell.DetailProperty.PropertyName) + { + tvc.DetailTextLabel.Text = ((TextCell)tvc.Cell).Detail; + tvc.DetailTextLabel.SizeToFit(); + } + else if (args.PropertyName == TextCell.TextColorProperty.PropertyName) + tvc.TextLabel.TextColor = textCell.TextColor.ToUIColor(DefaultTextColor); + else if (args.PropertyName == TextCell.DetailColorProperty.PropertyName) + tvc.DetailTextLabel.TextColor = textCell.DetailColor.ToUIColor(DefaultTextColor); + else if (args.PropertyName == Cell.IsEnabledProperty.PropertyName) + UpdateIsEnabled(tvc, textCell); + } + + static void UpdateIsEnabled(CellTableViewCell cell, TextCell entryCell) + { + cell.UserInteractionEnabled = entryCell.IsEnabled; + cell.TextLabel.Enabled = entryCell.IsEnabled; + cell.DetailTextLabel.Enabled = entryCell.IsEnabled; + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs new file mode 100644 index 00000000..b1416295 --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs @@ -0,0 +1,176 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +#if __UNIFIED__ +using UIKit; +#else +using MonoTouch.UIKit; +using System.Drawing; +#endif +#if __UNIFIED__ +using RectangleF = CoreGraphics.CGRect; +using SizeF = CoreGraphics.CGSize; +using PointF = CoreGraphics.CGPoint; + +#else +using nfloat=System.Single; +using nint=System.Int32; +using nuint=System.UInt32; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class ViewCellRenderer : CellRenderer + { + public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) + { + var viewCell = (ViewCell)item; + + var cell = reusableCell as ViewTableCell; + if (cell == null) + cell = new ViewTableCell(item.GetType().FullName); + else + cell.ViewCell.PropertyChanged -= ViewCellPropertyChanged; + + viewCell.PropertyChanged += ViewCellPropertyChanged; + cell.ViewCell = viewCell; + + WireUpForceUpdateSizeRequested(item, cell, tv); + + UpdateBackground(cell, item); + UpdateIsEnabled(cell, viewCell); + return cell; + } + + static void UpdateIsEnabled(ViewTableCell cell, ViewCell viewCell) + { + cell.UserInteractionEnabled = viewCell.IsEnabled; + cell.TextLabel.Enabled = viewCell.IsEnabled; + } + + void ViewCellPropertyChanged(object sender, PropertyChangedEventArgs e) + { + var viewCell = (ViewCell)sender; + var realCell = (ViewTableCell)GetRealCell(viewCell); + + if (e.PropertyName == Cell.IsEnabledProperty.PropertyName) + UpdateIsEnabled(realCell, viewCell); + } + + internal class ViewTableCell : UITableViewCell, INativeElementView + { + WeakReference<IVisualElementRenderer> _rendererRef; + + ViewCell _viewCell; + + public ViewTableCell(string key) : base(UITableViewCellStyle.Default, key) + { + } + + public ViewCell ViewCell + { + get { return _viewCell; } + set + { + if (_viewCell == value) + return; + UpdateCell(value); + } + } + + Element INativeElementView.Element + { + get { return ViewCell; } + } + + public override void LayoutSubviews() + { + //This sets the content views frame. + base.LayoutSubviews(); + + var contentFrame = ContentView.Frame; + + Layout.LayoutChildIntoBoundingRegion(ViewCell.View, contentFrame.ToRectangle()); + + if (_rendererRef == null) + return; + + IVisualElementRenderer renderer; + if (_rendererRef.TryGetTarget(out renderer)) + renderer.NativeView.Frame = contentFrame; + } + + public override SizeF SizeThatFits(SizeF size) + { + IVisualElementRenderer renderer; + if (!_rendererRef.TryGetTarget(out renderer)) + return base.SizeThatFits(size); + + double width = size.Width; + var height = size.Height > 0 ? size.Height : double.PositiveInfinity; + var result = renderer.Element.Measure(width, height); + + // make sure to add in the separator + return new SizeF(size.Width, (float)result.Request.Height + 1f / UIScreen.MainScreen.Scale); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + IVisualElementRenderer renderer; + if (_rendererRef != null && _rendererRef.TryGetTarget(out renderer) && renderer.Element != null) + { + var platform = renderer.Element.Platform as Platform; + if (platform != null) + platform.DisposeModelAndChildrenRenderers(renderer.Element); + + _rendererRef = null; + } + } + + base.Dispose(disposing); + } + + IVisualElementRenderer GetNewRenderer() + { + var newRenderer = Platform.CreateRenderer(_viewCell.View); + _rendererRef = new WeakReference<IVisualElementRenderer>(newRenderer); + ContentView.AddSubview(newRenderer.NativeView); + return newRenderer; + } + + void UpdateCell(ViewCell cell) + { + if (_viewCell != null) + Device.BeginInvokeOnMainThread(_viewCell.SendDisappearing); + + _viewCell = cell; + Device.BeginInvokeOnMainThread(_viewCell.SendAppearing); + + IVisualElementRenderer renderer; + if (_rendererRef == null || !_rendererRef.TryGetTarget(out renderer)) + renderer = GetNewRenderer(); + else + { + if (renderer.Element != null && renderer == Platform.GetRenderer(renderer.Element)) + renderer.Element.ClearValue(Platform.RendererProperty); + + var type = Registrar.Registered.GetHandlerType(_viewCell.View.GetType()); + if (renderer.GetType() == type || (renderer is Platform.DefaultRenderer && type == null)) + renderer.SetElement(_viewCell.View); + else + { + //when cells are getting reused the element could be already set to another cell + //so we should dispose based on the renderer and not the renderer.Element + var platform = renderer.Element.Platform as Platform; + platform.DisposeRendererAndChildren(renderer); + renderer = GetNewRenderer(); + } + } + + Platform.SetRenderer(_viewCell.View, renderer); + } + } + } +}
\ No newline at end of file |