summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs
diff options
context:
space:
mode:
authorJason Smith <jason.smith@xamarin.com>2016-03-22 13:02:25 -0700
committerJason Smith <jason.smith@xamarin.com>2016-03-22 16:13:41 -0700
commit17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch)
treeb5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs
downloadxamarin-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.cs176
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