Reputation: 72222
I swear I've searched the entire Google database for a possible solution but I'm still stuck on this issue :)
Basically, I have 12 rows in a database table for which I generate a custom UITableViewCell with 4 UITextFields inside. The table columns look like this (SQLITE)
EntryFieldID NUMBER
Description TEXT
FieldType TEXT
Now I want each UITableViewCell
Tag to be the EntryFieldID
above so I can easily refer to it back later for storing in another table. That table looks like this.
OrderID NUMBER
EntryFieldID NUMBER
Value1 TEXT
Value2 TEXT
Value3 TEXT
Value4 TEXT
The 4 Value* fields are the 4 UITextFields
that are inside each the UIViewCell
.
Hopefully this makes sense so far :)
Now inside my TableViewSource I have this code:
protected List<InfoCaptureTableViewGroup> _tableItems;
protected string _customCellIdentifier = "InfoCaptureField";
protected Dictionary<int, InfoCaptureTableViewCell> _cellControllers = new Dictionary<int, InfoCaptureTableViewCell>();
public InfoCaptureTableSource (List<InfoCaptureTableViewGroup> items)
{
this._tableItems = items;
}
/// <summary>
/// Called by the TableView to determine how many sections(groups) there are.
/// </summary>
public override int NumberOfSections (UITableView tableView)
{
return this._tableItems.Count;
}
/// <summary>
/// Called by the TableView to determine how many cells to create for that particular section.
/// </summary>
public override int RowsInSection (UITableView tableview, int section)
{
return this._tableItems[section].Items.Count;
}
/// <summary>
/// Called by the TableView to retrieve the header text for the particular section(group)
/// </summary>
public override string TitleForHeader (UITableView tableView, int section)
{
return this._tableItems[section].Name;
}
/// <summary>
/// Called by the TableView to retrieve the footer text for the particular section(group)
/// </summary>
public override string TitleForFooter (UITableView tableView, int section)
{
return this._tableItems[section].Footer;
}
/// <summary>
/// Called by the TableView to retreive the height of the row for the particular section and row
/// </summary>
public override float GetHeightForRow (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
return 44f;
}
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
// is there a way to NOT reuse cells? There's only ever going to be 12 of them
UITableViewCell cell = tableView.DequeueReusableCell (this._customCellIdentifier);
InfoCaptureTableViewCell customCellController = null;
InfoCaptureField item = this._tableItems[indexPath.Section].Items[indexPath.Row];
//---- if there are no cells to reuse, create a new one
if (cell == null)
{
customCellController = new InfoCaptureTableViewCell();
// retrieve the cell from our custom cell controller
cell = customCellController.Cell;
// disable selection
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
// This is where I'd like to use the EntryFieldID
cell.Tag = Environment.TickCount;
// store our controller with the unique ID we gave our cell
this._cellControllers.Add (cell.Tag, customCellController);
}
else
{
// retrieve our controller via it's unique ID
customCellController = this._cellControllers[cell.Tag];
}
//---- return the custom cell
return cell;
}
The code above doesn't actually make too much sense to me, it was copied from a MonoTouch example. I understand that cells get reused but I'd actually like to avoid this so I can use the EntryFieldID for the custom cell's Tag property AND also so that I can loop through all rows of the UITableView (which I now understand might not be possible).
So, if someone could shed some light on my current approach, whether it's feasible or not, or whether I should be looking at re-implementing the whole thing all-together.
Upvotes: 2
Views: 1096
Reputation: 32694
You would do yourself a big favor if you do not consider UITableViewCells as building blocks for your application that hold state, but for what they are: transient objects that are created and destroyed on demand for rendering information.
If you make that leap in your thinking about the UITableViewCell, you will realize that whatever happens on the cell in terms of changes to any particular control or data structures, needs to be reflected elsewhere.
The first problem that you have with your code is that you are using the cells the way they were intended to be used: by reusing an existing cell from the queue, but then you decide that this is not what you wanted and you are trying to use a different lookup system. So that is why your approach wont work.
You have a few options:
(a) Use UITableViewCells the way they are supposed to be used. This could be annoying, but there are tools that make this a lot simpler, things like MonoTouch.Dialog or you can check my blog entry on design patterns for uitableviewcells:
http://tirania.org/monomac/archive/2011/Jan-18.html
(b) You could instead of reusing the same cell identifier in your code, use one cell identifier for each row. This will force the UITableView to create new cells, one per row that you want to later look up. If all you are going to have are 12 rows, this should be no problem.
Upvotes: 7
Reputation: 16719
The best way would be not implementing your own cell view but just implementing the custom view and adding it to the cell's contentView as the subview.
so every you're accessing GetCell you have to replace contentView subviews with your custom one.
Not reusing the cell is bad idea, cause you'll probably have problems with selection, accessory views etc.
Upvotes: 1