Skip to content

Instantly share code, notes, and snippets.

@julesx
Last active May 9, 2017 18:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save julesx/f8560e10e68ac0352b5a631bd58f954a to your computer and use it in GitHub Desktop.
Save julesx/f8560e10e68ac0352b5a631bd58f954a to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using CoreGraphics;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(MyTextCell), typeof(AccessorizedTextCellRenderer))]
[assembly: ExportRenderer(typeof(MyImageCell), typeof(AccessorizedImageCellRenderer))]
[assembly: ExportRenderer(typeof(MyViewCell), typeof(AccessorizedViewCellRenderer))]
namespace MyApp.iOS.Renderers
{
internal class CellAccessory
{
private static List<CellAccessory> _watchedCells = new List<CellAccessory>();
internal static void Apply(Cell cell, UITableViewCell nativeCell)
{
CellAccessory watchedCell = null;
// look to see if we are already tracking this xaml cell
foreach (var item in _watchedCells.ToArray())
{
Cell cellRef;
if (item._cell.TryGetTarget(out cellRef))
{
if (cellRef == cell)
{
watchedCell = item;
break;
}
}
else
{
// remove dead entry from list
_watchedCells.Remove(item);
}
}
// if not already tracking, set up new entry and monitor for property changes
if (watchedCell == null)
{
watchedCell = new CellAccessory { _cell = new WeakReference<Cell>(cell) };
cell.PropertyChanged += watchedCell.CellPropertyChanged;
_watchedCells.Add(watchedCell);
}
// update the target native cell of the tracked xaml cell
watchedCell._nativeCell = new WeakReference<UITableViewCell>(nativeCell);
// force immediate update of accessory type
watchedCell.Reapply();
}
private WeakReference<Cell> _cell;
private WeakReference<UITableViewCell> _nativeCell;
private void CellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
var myTextCell = sender as MyTextCell;
var myImageCell = sender as MyImageCell;
var myViewCell = sender as MyViewCell;
string accessory = null;
if (myTextCell != null)
accessory = myTextCell.Accessory.ToString();
else if (myImageCell != null)
accessory = myImageCell.Accessory.ToString();
else if (myViewCell != null)
accessory = myViewCell.Accessory.ToString();
// update native accessory type when xaml property changes
if (args.PropertyName == accessory)
Reapply();
}
private void Reapply()
{
Cell cell;
UITableViewCell nativeCell;
if (!_cell.TryGetTarget(out cell))
{
// remove dead entry from list
_watchedCells.Remove(this);
return;
}
if (!_nativeCell.TryGetTarget(out nativeCell))
{
// if a property change fires for a dead native cell (but xaml cell isn't dead), then ignore it
return;
}
var myTextCell = cell as MyTextCell;
var myImageCell = cell as MyImageCell;
var myViewCell = cell as MyViewCell;
AccessoryType acc = AccessoryType.None;
if (myTextCell != null)
acc = myTextCell.Accessory;
else if (myImageCell != null)
acc = myImageCell.Accessory;
else if (myViewCell != null)
acc = myViewCell.Accessory;
//var acc = (AccessoryType)cell.GetValue(MyViewCell.AccessoryProperty);
switch (acc)
{
case AccessoryType.None:
nativeCell.Accessory = UITableViewCellAccessory.None;
if (nativeCell.AccessoryView == null)
nativeCell.AccessoryView = new UIView(new CGRect(0, 0, 20, 40));
return;
case AccessoryType.Checkmark:
nativeCell.Accessory = UITableViewCellAccessory.Checkmark;
break;
case AccessoryType.DisclosureIndicator:
nativeCell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
break;
case AccessoryType.DetailButton:
nativeCell.Accessory = UITableViewCellAccessory.DetailButton;
break;
case AccessoryType.DetailDisclosureButton:
nativeCell.Accessory = UITableViewCellAccessory.DetailDisclosureButton;
break;
}
if (nativeCell.AccessoryView != null)
nativeCell.AccessoryView.Dispose();
nativeCell.AccessoryView = null;
}
}
public class AccessorizedTextCellRenderer : TextCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
CellAccessory.Apply(item, cell);
return cell;
}
}
public class AccessorizedImageCellRenderer : ImageCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
CellAccessory.Apply(item, cell);
return cell;
}
}
public class AccessorizedViewCellRenderer : ViewCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
CellAccessory.Apply(item, cell);
return cell;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment