iOS Navigating to New View on Table Cell Click using a Segue - ios

Upon clicking a table cell I would like to navigate to a new page using a segue. However whenever I click the cell nothing happens.
When I place a breakpoint on the PrepareForSegue method it is never hit when I click a cell on the DayTableView.
Main.storyboard
DayTableViewController
namespace HHGoals2
{
public partial class DayTableViewController : UITableViewController
{
HHGoals2DataService dataService = new HHGoals2DataService();
public DayTableViewController(IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad()
{
var allDays = dataService.GetAllDays();
var dataSource = new GoalsDataSource(allDays, this);
TableView.Source = dataSource;
this.NavigationItem.Title = "Completed Goals";
}
public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue(segue, sender);
if(segue.Identifier == "GoalDetailSegue")
{
var goalDetailViewController = segue.DestinationViewController
as GoalDetailViewController;
if(goalDetailViewController != null)
{
var source = TableView.Source as GoalsDataSource;
var rowPath = TableView.IndexPathForSelectedRow;
var item = source.GetItem(rowPath.Row);
goalDetailViewController.SelectedDay = item;
}
}
}
}
}
GoalsDataSource
using System;
using Foundation;
using UIKit;
using System.Collections.Generic;
using HHGoals2.Core.Model;
using HHGoals2.Cells;
namespace HHGoals2.DataSources
{
public class GoalsDataSource: UITableViewSource
{
private List<Day> allDays;
NSString cellIdentifier = new NSString("DayCell");
DayTableViewController callingController;
public GoalsDataSource(List<Day> allDays, DayTableViewController callingController)
{
this.allDays = allDays;
this.callingController = callingController;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
DayListCell cell = tableView.DequeueReusableCell(cellIdentifier) as DayListCell;
if (cell == null)
{
cell = new DayListCell(cellIdentifier);
}
cell.UpdateCell(allDays[indexPath.Row].Number.ToString(),
allDays[indexPath.Row].SuccessRate.ToString(),
allDays[indexPath.Row].FailRate.ToString());
return cell;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return allDays.Count;
}
public Day GetItem(int id)
{
return allDays[id];
}
}
}
Do I need to add a TouchUpInside event of the DayCell? Any suggestions on how to get this to work would be great.

I think you just missed out to connect the delegate and datasource to tableview in uitableviewcontroller. So connect it and it will work fine.

Related

UICollectionView with section layout issue in Xamarin Native

I have UIcollectionView with 8 sections. Each section has a dedicated array as the data source. I want to add an item to each section on a button press. UICollectionView scroll direction set to Horizontal because I want the sections to be vertical direction.
Everything working fine in Xcode project(Xib and Objective-C) as this screenshot(Red colored items are the items added on button press).
When I do the same implementation in Xamarin ios, the layout become a mess after press the button as bellow.
My code as bellow
public partial class GridViewController : UIViewController
{
CVSource source;
int MAX_NUMBER_OF_ROWS = 4;
public GridViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
//this.collectionView.SetNeedsDisplay();
this.collectionView.RegisterClassForCell(typeof(ItemCell), ItemCell.CellId);
source = new CVSource();
this.collectionView.DataSource = source;
}
partial void AddButtonPressed(UIButton sender)
{
Console.WriteLine("Add button pressed");
MAX_NUMBER_OF_ROWS = MAX_NUMBER_OF_ROWS + 1;
source.AddItem();
collectionView.Layer.RemoveAllAnimations();
collectionView.ReloadData();
ViewDidLayoutSubviews();
}
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
collectionView.Frame = new CoreGraphics.CGRect(collectionView.Frame.Location.X, collectionView.Frame.Location.Y, collectionView.Frame.Size.Width, MAX_NUMBER_OF_ROWS * 40);
btnAdd.Frame = new CoreGraphics.CGRect(btnAdd.Frame.Location.X, collectionView.Frame.Location.Y + collectionView.Frame.Size.Height + 10, btnAdd.Frame.Size.Width, btnAdd.Frame.Size.Height);
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
DataSource class
class CVSource : UICollectionViewSource
{
List<string> arr1 = new List<string> { "40", "30"};
List<string> arr2 = new List<string> { "25", "22" };
List<string> arr3 = new List<string> { "35", "67" };
List<string> arr4 = new List<string> { "26", "12" };
List<string> arr5 = new List<string> { "27", "21", };
List<string> arr6 = new List<string> { "12", "45" };
List<string> arr7 = new List<string> { "34", "67" };
List<string> arr8 = new List<string> { "21", "44", };
public override nint NumberOfSections(UICollectionView collectionView)
{
return 8;
}
public override nint GetItemsCount(UICollectionView collectionView, nint section)
{
if ((int)section == 0)
return arr1.Count;
else if ((int)section == 1)
return arr2.Count;
else if ((int)section == 2)
return arr3.Count;
else if ((int)section == 3)
return arr4.Count;
else if ((int)section == 4)
return arr5.Count;
else if ((int)section == 5)
return arr6.Count;
else if ((int)section == 6)
return arr7.Count;
else if ((int)section == 7)
return arr8.Count;
return 0;
}
public override UICollectionViewCell GetCell(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
var itemCell = (ItemCell)collectionView.DequeueReusableCell(ItemCell.CellId, indexPath);
if (indexPath.Section == 0)
{
itemCell.SetText(arr1[indexPath.Row]);
}
else if (indexPath.Section == 1)
{
itemCell.SetText(arr2[indexPath.Row]);
}
else if (indexPath.Section == 2)
{
itemCell.SetText(arr3[indexPath.Row]);
}
else if (indexPath.Section == 3)
{
itemCell.SetText(arr4[indexPath.Row]);
}
else if (indexPath.Section == 4)
{
itemCell.SetText(arr5[indexPath.Row]);
}
else if (indexPath.Section == 5)
{
itemCell.SetText(arr6[indexPath.Row]);
}
else if (indexPath.Section == 6)
{
itemCell.SetText(arr7[indexPath.Row]);
}
else if (indexPath.Section == 7)
itemCell.SetText(arr8[(indexPath.Row)]);
return itemCell;
}
public override void ItemSelected(UICollectionView collectionView, NSIndexPath indexPath)
{
Console.WriteLine("Row selected "+ indexPath.Row);
}
public void AddItem()
{
arr1.Add("0");
arr2.Add("0");
arr3.Add("0");
arr4.Add("0");
arr5.Add("0");
arr6.Add("0");
arr7.Add("0");
arr8.Add("0");
}
}
ItemCell class
public partial class ItemCell : UICollectionViewCell
{
public static readonly NSString CellId = new NSString("ItemCell");
public static UITextField txtFld;
[Export("initWithFrame:")]
public ItemCell(CGRect frame) : base(frame)
{
BackgroundView = new UIView { BackgroundColor = UIColor.Orange };
SelectedBackgroundView = new UIView { BackgroundColor = UIColor.Green };
ContentView.Layer.BorderColor = UIColor.LightGray.CGColor;
ContentView.Layer.BorderWidth = 2.0f;
ContentView.BackgroundColor = UIColor.White;
ContentView.Transform = CGAffineTransform.MakeScale(0.8f, 0.8f);
txtFld = new UITextField() { Frame = new CGRect(5.0, 5.0, 60.0, 30.0), KeyboardType = UIKeyboardType.DecimalPad };
}
}
Im not a Xamarin developer, appreciate any comments/suggestions from Xamarin experts
Maybe you miss UICollectionViewLayout to set for collectionView , you can set the GridLayout for collectionView to have a try .
this.collectionView.SetCollectionViewLayout(new GridLayout(), true); //add CollectionViewLayout
this.collectionView.RegisterClassForCell(typeof(ItemCell), ItemCell.CellId);
GridLayout inherits from UICollectionViewFlowLayout in Xamrarin iOS :
public class GridLayout : UICollectionViewFlowLayout
{
public GridLayout ()
{
}
public override bool ShouldInvalidateLayoutForBoundsChange (CGRect newBounds)
{
return true;
}
public override UICollectionViewLayoutAttributes LayoutAttributesForItem (NSIndexPath path)
{
return base.LayoutAttributesForItem (path);
}
public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect (CGRect rect)
{
return base.LayoutAttributesForElementsInRect (rect);
}
}
The effect :
Affter tried the shared code , the effect as follow :
The different with your codes only here :
public ViewController (IntPtr handle) : base (handle)
{
collectionView = new UICollectionView(new CGRect(0, 0, UIScreen.MainScreen.Bounds.Size.Width, 300), new GridLayout());
collectionView.RegisterClassForCell(typeof(ItemCell), ItemCell.CellId);
//collectionView.SetCollectionViewLayout(new GridLayout(), true);
collectionView.BackgroundColor = UIColor.Blue;
source = new CVSource();
collectionView.DataSource = source;
View.AddSubview(collectionView);
button = new UIButton(new CGRect(150, 400, 100, 50));
button.SetTitle("Hello", UIControlState.Normal);
button.BackgroundColor = UIColor.Red;
View.AddSubview(button);
button.TouchUpInside += Button_TouchUpInside;
}
Note : I use code to create Interface , and set GridLayout for CollectionView .Here is the sample link .

Not able find UITableViewCellDeleteConfirmationView in ios 11 layoutsubview subview in UITableviewcell?

I have to override the height swipe delete button in Tableviewcell i used the below code it's work fine ios 10 but in ios11 i can't able find the UITableViewCellDeleteConfirmationView in layoutsubview class
foreach (var views in this.Subviews)
{
if (views.Class.Name.ToString() == new NSString("UITableViewCellDeleteConfirmationView"))
{
CGRect newFrame = views.Frame;
CGRect newframe1 = new CGRect(newFrame.X, 6, newFrame.Size.Width, 59);
views.Frame = newframe1;
foreach (var getButtonviews in views.Subviews)
{
Console.WriteLine("x:"+getButtonviews.Frame.X);
Console.WriteLine("W:"+getButtonviews.Frame.Width);
if (getButtonviews.Class.Name.ToString() == "_UITableViewCellActionButton")
{
UIImage image = UIImage.FromBundle("img_line");
UIButton button = (UIButton)getButtonviews;
UIImageView imageview = new UIImageView();
imageview.Frame = new CGRect(getButtonviews.Frame.X + 120, 0, 1, getButtonviews.Frame.Height);
imageview.Image = image;
button.AddSubview(imageview);
foreach (var getButton in getButtonviews.Subviews)
{
if (getButton.Class.Name.ToString() == "UIButtonLabel")
{
UILabel label = (UILabel)getButton;
label.Font = UIFont.FromName("ProximaNova-Regular", 13);
}
}
}
}
}
}
The view hierarchy inside tableview has been changed after iOS10.
iOS8 - iOS10
UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView -> _UITableViewCellActionButton
iOS11
work with Xcode8
UITableView -> UITableViewWrapperView -> UISwipeActionPullView -> UISwipeActionStandardButton
work with Xcode9
UITableView -> UISwipeActionPullView -> UISwipeActionStandardButton
Solution:
I make the code work both at iOS8 - iOS11, and I put all the code at ViewWillLayoutSubviews in ViewController , but first , we need to know which cell we are selecting.
public class TableDelegate : UITableViewDelegate
{
YourViewController owner;
public TableDelegate(YourViewController vc){
owner = vc;
}
public override UITableViewRowAction[] EditActionsForRow(UITableView tableView, NSIndexPath indexPath)
{
UITableViewRowAction hiButton = UITableViewRowAction.Create(
UITableViewRowActionStyle.Default,
"Hi",
delegate {
Console.WriteLine("Hello World!");
});
return new UITableViewRowAction[] { hiButton };
}
public override void WillBeginEditing(UITableView tableView, NSIndexPath indexPath)
{
owner.selectIndexPath = indexPath;
owner.View.SetNeedsLayout();
}
public override void DidEndEditing(UITableView tableView, NSIndexPath indexPath)
{
owner.selectIndexPath = null;
}
}
public class TableSource : UITableViewSource
{
string[] TableItems;
string CellIdentifier = "TableCell";
public TableSource(string[] items)
{
TableItems = items;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return TableItems.Length;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
string item = TableItems[indexPath.Row];
//---- if there are no cells to reuse, create a new one
if (cell == null)
{ cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier); }
cell.TextLabel.Text = item;
return cell;
}
}
public partial class ViewController : UIViewController
{
protected ViewController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public NSIndexPath selectIndexPath { get; set; }
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
string[] tableItems = new string[] { "Vegetables", "Fruits", "Flower Buds", "Legumes", "Bulbs", "Tubers" };
tableview.Source = new TableSource(tableItems);
tableview.Delegate = new TableDelegate(this);
}
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
if (this.selectIndexPath != null)
{
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
// Code that uses features from iOS 11.0 and later
foreach (UIView subview in tableview.Subviews)
{
if (subview.Class.Name.ToString() == "UISwipeActionPullView")
{
foreach (var buttonViews in subview.Subviews)
{
if (buttonViews.Class.Name.ToString() == "UISwipeActionStandardButton")
{
//operate what you want.
}
}
}
}
}
else
{
// Code to support earlier iOS versions
UITableViewCell cell = tableview.CellAt(this.selectIndexPath);
foreach (UIView subview in cell.Subviews)
{
if (subview.Class.Name.ToString() == "UITableViewCellDeleteConfirmationView")
{
foreach (var buttonViews in subview.Subviews)
{
if (buttonViews.Class.Name.ToString() == "_UITableViewCellActionButton")
{
//operate what you want.
}
}
}
}
}
}
}
}

Xamarin - UITableView reload data for array

I implemented UITableView on Xamarin using a new class for TableSource. I am initializing TableSource from MainView and pass an array. Then I am trying to update that array from MainView and I am getting error:
Object reference not sent to an instance
The code in MainVC:
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
//Console.WriteLine("Event 1");
lVM = new ListViewModel();
lVM.dataUpdated += this.updateArray;
lVM.dataUpdatedNetwork += this.networkUpdatedSQL;
lVM.getInitialData(100);
tableSource = new ListTableSource(this);
tableV.Source = tableSource;
}
public void updateArray(object sender, EventArgs e) {
InvokeOnMainThread(delegate
{
//Console.WriteLine("Update array event on VC for SQL count for array " + lVM.ordersArray.Count);
tableSource.updateArray(lVM.ordersArray);
tableV.ReloadData();
});
}
The code in TableSource:
public class ListTableSource : UITableViewSource
{
ListViewController listVCRef;
ArrayList tableItems;
string cellIdentifier = "TableCell";
public ListTableSource(ListViewController listVC)
{
tableItems = new ArrayList();
listVCRef = listVC;
}
public void updateArray(ArrayList items) {
tableItems = new ArrayList(items);
Console.WriteLine("Items " + tableItems.Count);
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
new UIAlertView("Alert", "You touched: " + tableItems[indexPath.Row], null, "OK", null).Show();
tableView.DeselectRow(indexPath, true);
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(cellIdentifier);
if (cell == null)
{
cell = new UITableViewCell(UITableViewCellStyle.Subtitle, cellIdentifier);
}
Order currentOrder = tableItems[indexPath.Row] as Order;
cell.TextLabel.Text = currentOrder.comment;
cell.DetailTextLabel.Text = currentOrder.orderDate.ToString();
return cell;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return tableItems.Count;
}
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return 80;
}
}
Is my approach wrong? How I am supposed to update the data in TableSource.
My feeling is that updateArray is executed before tableSource = new ListTableSource(this); and because of this tableSource is null. lVM.getInitialData(100); is likely triggering updateArray.
This worker for my:
button.TouchUpInside += (s, e) => {
tableItems.Add(textfield1.Text); //(1)
table = new UITableView(View.Bounds);
table.Source = new TableView(tableItems.ToArray()); //(2)
table.Frame = new CoreGraphics.CGRect(0, 350, this.View.Frame.Width, 300); //(3)
Add(table);
};
in (1) the list tableItems add new value of uiTextField
in (2) Actually the datas in Source of your table
in (3) create visually the table

Xamarin iOS 8, UICollectionView - Error in dequeue reusable UICollectionViewCell

I'm having some trouble implementing a UICollectionView in my UIViewController. It gives me an error in GetCell Failed to marshal the Objective-C object 0x137622db0 (type: ParkXApp_iOS_FamilyCollectionCell). Could not find an existing managed instance for this object, nor was it possible to create a new managed instance (because the type 'ParkXApp_iOS.FamilyCollectionCell' does not have a constructor that takes one IntPtr argument)..
I have implemented next to the monotouch sample code: monotouch sample simple UICollectionView
this is my code:
using System;
using UIKit;
using CoreGraphics;
using System.Collections.Generic;
using ObjCRuntime;
using Foundation;
namespace ParkXApp_iOS
{
public class FamilyView : UIViewController
{
nfloat navBarHeight;
nfloat viewWidth;
nfloat viewHeight;
public FamilyView ()
{
}
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
Draw ();
}
public void Draw () {
// clean the screen before (re)drawing it
foreach (var subView in this.View.Subviews) {
subView.RemoveFromSuperview ();
}
this.NavigationItem.SetRightBarButtonItem(null, true);
// set background
this.View.BackgroundColor = new UIColor((nfloat)0.99, (nfloat)0.99, (nfloat)0.99, 1);
// get viewWidth and viewHeight for drawing relative to the screen
navBarHeight = this.NavigationController.NavigationBar.Frame.GetMaxY ();
viewWidth = UIScreen.MainScreen.Bounds.Width;
viewHeight = UIScreen.MainScreen.Bounds.Height - navBarHeight;
UICollectionViewFlowLayout flowLayout = new UICollectionViewFlowLayout ();
flowLayout.ItemSize = new CGSize (100, 100);
flowLayout.ScrollDirection = UICollectionViewScrollDirection.Vertical;
flowLayout.SectionInset = new UIEdgeInsets (20, 20, 20, 20);
UICollectionView collectionView = new FamilyCollectionView (flowLayout).CollectionView;
collectionView.Frame = new CGRect (0, navBarHeight, viewWidth, viewHeight);
collectionView.ContentInset = new UIEdgeInsets (50, 0, 0, 0);
this.View.AddSubview (collectionView);
}
}
public class FamilyCollectionView : UICollectionViewController
{
List<string> familyMembers;
public FamilyCollectionView (UICollectionViewLayout layout) : base (layout) {
familyMembers = new List<string> ();
for (int i = 0; i < 5; i++) {
familyMembers.Add ("tom");
}
CollectionView.RegisterClassForCell (typeof(FamilyCollectionCell), "FamilyCollectionCell");
UIMenuController.SharedMenuController.MenuItems = new UIMenuItem[] {
new UIMenuItem ("Custom", new Selector ("custom"))
};
}
public override nint NumberOfSections (UICollectionView collectionView)
{
return 1;
}
public override nint GetItemsCount (UICollectionView collectionView, nint section)
{
return familyMembers.Count;
}
public override UICollectionViewCell GetCell (UICollectionView collectionView, Foundation.NSIndexPath indexPath)
{
try {
var cell = (FamilyCollectionCell)collectionView.DequeueReusableCell ("FamilyCollectionCell", indexPath);
cell.nameLabel.Text = familyMembers [indexPath.Row];
return cell;
} catch (Exception ex) {
Console.WriteLine (ex.Message);
}
return null;
}
public override void ItemHighlighted (UICollectionView collectionView, NSIndexPath indexPath)
{
var cell = collectionView.CellForItem (indexPath);
cell.ContentView.BackgroundColor = UIColor.Yellow;
}
public override void ItemUnhighlighted (UICollectionView collectionView, NSIndexPath indexPath)
{
var cell = collectionView.CellForItem (indexPath);
cell.ContentView.BackgroundColor = UIColor.White;
}
public override bool ShouldHighlightItem (UICollectionView collectionView, NSIndexPath indexPath)
{
return true;
}
}
public class FamilyCollectionCell : UICollectionViewCell
{
public UILabel nameLabel;
public FamilyCollectionCell (CGRect frame) : base (frame)
{
BackgroundColor = UIColor.Orange;
ContentView.Layer.BorderColor = UIColor.LightGray.CGColor;
ContentView.Layer.BorderWidth = 2.0f;
ContentView.BackgroundColor = UIColor.White;
ContentView.Transform = CGAffineTransform.MakeScale (0.8f, 0.8f);
nameLabel = new UILabel ();
nameLabel.Text = "name";
nameLabel.SizeToFit ();
nameLabel.Center = ContentView.Center;
ContentView.AddSubview (nameLabel);
}
[Export("custom")]
void Custom()
{
Console.WriteLine ("some code in the cell");
}
public override bool CanPerform (Selector action, NSObject withSender)
{
if (action == new Selector ("custom"))
return true;
else
return false;
}
}
}
To test it you should be able to copy-paste the code and run it in a solution. It is completely independent.
Thanks in advance!
You need to add this:
[Export ("initWithFrame:")]
in you cell like so
public class FamilyCollectionCell : UICollectionViewCell
{
public UILabel nameLabel;
[Export ("initWithFrame:")] // ADDED HERE
public FamilyCollectionCell (CGRect frame) : base (frame)
{
BackgroundColor = UIColor.Orange;
ContentView.Layer.BorderColor = UIColor.LightGray.CGColor;
ContentView.Layer.BorderWidth = 2.0f;
ContentView.BackgroundColor = UIColor.White;
ContentView.Transform = CGAffineTransform.MakeScale (0.8f, 0.8f);
nameLabel = new UILabel ();
nameLabel.Text = "name";
nameLabel.SizeToFit ();
nameLabel.Center = ContentView.Center;
ContentView.AddSubview (nameLabel);
}
[Export("custom")]
void Custom()
{
Console.WriteLine ("some code in the cell");
}
public override bool CanPerform (Selector action, NSObject withSender)
{
if (action == new Selector ("custom"))
return true;
else
return false;
}
}
Also that's an interesting way of adding in the collectionView into a viewcontroller. Is there any need for FamilyView? It might be better to add the navbar to the collectionview controller?

Xamarin UITableViewCell Memory Leak

I'm using Xamarin and classes that inherit UITableViewController, UITableViewSource, and UITableViewCell to provide a simple list of items.
I find that once garbage collection has run, the UITableViewController and UITableViewSource get collected, but the UITableViewCell's never get disposed and collected properly.
Here's my example code.
public class Test1ButtonCell : UITableViewCell
{
public static readonly NSString Key = new NSString("Test1ButtonCell");
public Test1ButtonCell () : base (UITableViewCellStyle.Default, Key)
{
TextLabel.TextColor = UIColor.Black;
TextLabel.TextAlignment = UITextAlignment.Left;
}
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
}
}
public class Test1Controller : UITableViewController
{
private WeakReference<Test1Source> source = null;
public Test1Controller () : base (UITableViewStyle.Grouped)
{
}
public override void DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
List<String> testdata = new List<String>( );
for( int i = 0; i < 30; i++ )
{
testdata.Add( i.ToString( ) );
}
source = new WeakReference<Test1Source>(new Test1Source( this,testdata ));
testdata = null;
this.NavigationItem.LeftBarButtonItem = new UIBarButtonItem ("Back", UIBarButtonItemStyle.Plain, null);
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear (animated);
this.NavigationItem.Title="Test1";
TableView.Source = source.target;
this.NavigationItem.LeftBarButtonItem.Clicked += HandleBackButtonTouch;
}
public override void ViewWillDisappear (bool animated)
{
this.NavigationItem.LeftBarButtonItem.Clicked -= HandleBackButtonTouch;
base.ViewWillDisappear (animated);
TableView.Source = null;
}
private void HandleBackButtonTouch(object sender, EventArgs e)
{
NavigationController.PopToRootViewController( true );
}
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
}
}
public class Test1Source : UITableViewSource
{
private WeakReference<Test1Controller> controller;
private List<String> testdata = new List<string>();
public Test1Source (Test1Controller controller, List<String> testData)
{
testdata = testData;
this.controller = new WeakReference<Test1Controller>( controller );
}
public override nint NumberOfSections (UITableView tableView)
{
return 1;
}
public override nint RowsInSection (UITableView tableview, nint section)
{
if( section == 0 )
{
return testdata.Count;
}
else
{
return 0;
}
}
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell (Test1ButtonCell.Key) as Test1ButtonCell;
if( cell == null )
{
cell = new Test1ButtonCell( );
}
if( indexPath.Section == 0 )
{
cell.TextLabel.Text = testdata[ indexPath.Row ];
}
return cell;
}
}
The UITableView caches (and reuses) UITableViewCells.
They'll go away once the UITableView is freed.
I can confirm the problem. It works properly on the simulator and not on the device.
The only thing I can think of is to keep somewhere list of all created custom cells (by adding them to the list in the constructor of the cell) and dispose them when the table is disposed. Kind of ugly, but it works.

Resources