Marko
Marko

Reputation: 72222

Retrieve values from UITextFields inside custom UITableViewCell

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

Answers (2)

miguel.de.icaza
miguel.de.icaza

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

Max
Max

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

Related Questions