Last active
May 9, 2017 18:27
-
-
Save julesx/f8560e10e68ac0352b5a631bd58f954a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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