Skip to content

Instantly share code, notes, and snippets.

@sgmunn
Created May 1, 2012 11:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgmunn/2567352 to your computer and use it in GitHub Desktop.
Save sgmunn/2567352 to your computer and use it in GitHub Desktop.
Event Handler in MonoTouch not allowing objects to be collected
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace UIDateFieldTest
{
public partial class UIDateFieldTestViewController : UIViewController
{
public UIDateFieldTestViewController() : base ("UIDateFieldTestViewController", null)
{
}
public override void DidReceiveMemoryWarning()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
}
public override void ViewDidUnload()
{
base.ViewDidUnload();
// Clear any references to subviews of the main view in order to
// allow the Garbage Collector to collect them sooner.
//
// e.g. myOutlet.Dispose (); myOutlet = null;
ReleaseDesignerOutlets();
}
public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)
{
// Return true for supported orientations
return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
}
partial void buttonClicked(MonoTouch.Foundation.NSObject sender)
{
var tbView = new UITableViewController();
tbView.TableView.DataSource = new TestSource();
this.NavigationController.PushViewController(tbView, true);
}
}
public class TestSource : UITableViewDataSource
{
public override int NumberOfSections(UITableView tableView)
{
return 1;
}
public override int RowsInSection(UITableView tableView, int section)
{
return 2;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
if (indexPath.Row == 0)
{
var cell1 = tableView.DequeueReusableCell(new NSString("Cell1"));
if (cell1 == null)
{
cell1 = new TextInputTableViewCell(UITableViewCellStyle.Default, new NSString("Cell1"));
}
return cell1;
}
var cell2 = tableView.DequeueReusableCell(new NSString("Cell2"));
if (cell2 == null)
{
cell2 = new DateInputTableViewCell(UITableViewCellStyle.Default, new NSString("Cell2"));
}
return cell2;
}
}
public class TextInputTableViewCell : UITableViewCell
{
private UITextField textField;
public TextInputTableViewCell(UITableViewCellStyle style, NSString reuseIdentifer)
: base(style, reuseIdentifer)
{
this.ConfigureCell();
}
public UITextField TextField
{
get
{
return this.textField;
}
}
protected override void Dispose (bool disposing)
{
Console.WriteLine("dispose textField {0}", disposing);
if (disposing)
{
this.textField.Dispose();
this.textField = null;
}
base.Dispose (disposing);
}
protected void ConfigureCell ()
{
this.SelectionStyle = UITableViewCellSelectionStyle.None;
this.textField = new UITextField(this.CalculateTextFieldFrame(string.Empty))
{
VerticalAlignment = UIControlContentVerticalAlignment.Center,
ClearButtonMode = UITextFieldViewMode.WhileEditing,
};
this.textField.Font = UIFont.SystemFontOfSize(17);
this.textField.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin;
this.ContentView.AddSubview(this.textField);
this.textField.Ended += this.TextValueChanged;
}
private void TextValueChanged(object sender, EventArgs args)
{
}
private RectangleF CalculateTextFieldFrame(string textValue)
{
float margin = 10;
var textSize = new RectangleF (margin, 10, this.ContentView.Bounds.Width - (margin * 2), this.ContentView.Bounds.Height - (margin * 2));
if (!String.IsNullOrEmpty(textValue))
{
var sz = this.CalculateEntrySize(null);
textSize = new RectangleF (sz.Width, (this.ContentView.Bounds.Height - sz.Height) / 2 - 1, sz.Width * 2 - margin, sz.Height);
}
return textSize;
}
private SizeF CalculateEntrySize (UITableView tv)
{
var sz = this.StringSize("W", UIFont.SystemFontOfSize (17));
float w = this.ContentView.Bounds.Width / 3;
return new SizeF(w, sz.Height);
}
}
public class DateInputTableViewCell : UITableViewCell
{
private UIDateField dateField;
public DateInputTableViewCell(UITableViewCellStyle style, NSString reuseIdentifer)
: base(style, reuseIdentifer)
{
this.ConfigureCell();
}
protected override void Dispose (bool disposing)
{
Console.WriteLine("dispose ..{0}", disposing);
if (disposing)
{
this.dateField.Dispose();
this.dateField = null;
}
base.Dispose (disposing);
}
protected void ConfigureCell ()
{
this.SelectionStyle = UITableViewCellSelectionStyle.None;
this.dateField = new UIDateField(this.CalculateTextFieldFrame(string.Empty))
{
AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin,
};
this.ContentView.AddSubview(this.dateField);
// FIXME: More investigation required here, hooking this handler up causes the datefield and the table cell to be not collected
this.dateField.ValueChanged += this.DateValueChanged;
}
private void DateValueChanged(object sender, EventArgs args)
{
}
private RectangleF CalculateTextFieldFrame(string textValue)
{
float margin = 10;
var textSize = new RectangleF (margin, 10, this.ContentView.Bounds.Width - (margin * 2), this.ContentView.Bounds.Height - (margin * 2));
if (!String.IsNullOrEmpty(textValue))
{
var sz = this.CalculateEntrySize(null);
textSize = new RectangleF (sz.Width, (this.ContentView.Bounds.Height - sz.Height) / 2 - 1, sz.Width * 2 - margin, sz.Height);
}
return textSize;
}
private SizeF CalculateEntrySize (UITableView tv)
{
var sz = this.StringSize("W", UIFont.SystemFontOfSize (17));
float w = this.ContentView.Bounds.Width / 3;
return new SizeF(w, sz.Height);
}
}
public class UIDateField : UIControl
{
private DateTime date;
private UIDatePicker picker;
private UILabel label;
private string dateFormat;
private UIView accessoryView;
public UIDateField(RectangleF frame) : base(frame)
{
this.dateFormat = "D";
this.picker = new UIDatePicker();
this.picker.Mode = UIDatePickerMode.Date;
this.picker.TimeZone = NSTimeZone.FromAbbreviation("GMT");
this.picker.ValueChanged += this.PickerValueChanged;
this.label = new UILabel(this.Bounds);
this.label.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin;
this.label.BackgroundColor = UIColor.Green;
this.label.UserInteractionEnabled = false;
this.AddSubview(this.label);
this.Date = DateTime.Today;
}
~UIDateField()
{
Console.WriteLine("UIDateField");
}
public override bool CanBecomeFirstResponder
{
get
{
return this.Enabled;
}
}
public override UIView InputView
{
get
{
return this.picker;
}
}
[Export("inputAccessoryView")]
public new UIView InputAccessoryView
{
get
{
return this.accessoryView;
}
set
{
this.accessoryView = value;
}
}
public DateTime Date
{
get
{
return this.date;
}
set
{
if (value != this.date)
{
this.date = value;
this.picker.Date = DateTime.SpecifyKind(value, DateTimeKind.Utc);
this.label.Text = this.date.ToString(this.DateFormat);
}
}
}
public string DateFormat
{
get
{
return this.dateFormat;
}
set
{
this.dateFormat = value;
this.label.Text = this.date.ToString(this.DateFormat);
}
}
public override void TouchesEnded(MonoTouch.Foundation.NSSet touches, UIEvent evt)
{
base.TouchesEnded(touches, evt);
if (evt.Type == UIEventType.Touches)
{
if (this.IsFirstResponder)
{
this.ResignFirstResponder();
}
else
{
this.BecomeFirstResponder();
}
}
}
protected override void Dispose(bool disposing)
{
Console.WriteLine("dispose UIDateField");
if (disposing)
{
this.picker.Dispose();
this.picker = null;
this.label.Dispose();
this.label = null;
}
base.Dispose(disposing);
}
private void PickerValueChanged(object sender, EventArgs args)
{
this.Date = DateTime.SpecifyKind(this.picker.Date, DateTimeKind.Unspecified);
this.SendActionForControlEvents(UIControlEvent.ValueChanged);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment