diff options
author | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 13:02:25 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 16:13:41 -0700 |
commit | 17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch) | |
tree | b5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs | 176 |
1 files changed, 176 insertions, 0 deletions
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 |