competent_tech
competent_tech

Reputation: 44931

How to remove cells that can be reused in UITableView (MonoTouch)

We have a scenario where we reuse the same UITableView to display different sets of records from the database as a user selects an item in a different UITableView (similar in concept to a splitviewcontroller, but all in the same view).

When the user selects a different area to view, we fetch the appropriate records from the database, update the Source with the new set of records, and call ReloadData.

The problem is that some of the cells in the UITableView still exist and are reused when switching between lists, resulting in invalid or overlapped data for various rows.

The question I have is: is there a method whereby we can tell the UITableView to discard all existing cells including those queued for reuse? I would have expected ReloadData to perform this task, but it does not.

Update with additional clarification:

Each cell in our table is composed of a variable number of subviews (we are trying to mimic a grid control). When the user selects a different list in the left-hand navigation, there is no guarantee that the subview positions (columns) in the newly selected list will overlap with those in the previous list. This is why we are looking for a method to remove the queued cells.

Upvotes: 1

Views: 990

Answers (3)

miguel.de.icaza
miguel.de.icaza

Reputation: 32694

Your GetCell method needs to ensure that a dequeued cell is fully configured with the new data that it is going to display.

A common mistake is assuming that just dequeuing the cell for display will give you a fresh cell that you can use.

If you have done any customization with your cell, like adding views, modifies its properties (images, disclosure indicators, background colors) you must make sure in the GetCell method that is reusing a cell that every single one of those properties is properly set before returning the cell.

Upvotes: 0

competent_tech
competent_tech

Reputation: 44931

Since this is a situation that others may find themselves in, I will post the solution that we used, but am still interested in more "native" ways of doing this.

Here is how we solved the issue:

When the set of records being displayed is changed, we update the UITableView with a unique identifier for the current cell configuration (i.e. which list of data is the user currently viewing).

We then created a custom version of UITableViewCell and record the unique list identifier in the cell when it is created.

When we dequeue a reusable cell, we compare the view's current unique identifier with the unique identifier stored in the cell and, if they don't match, we discard the cell and create a new one.

Hopefully this will help someone down the road.

Upvotes: 1

bryanmac
bryanmac

Reputation: 39296

ReloadData does not clear the re-use queue. It simply triggers the callbacks to re-read the data which reloads the rows. As each cell get's loaded, if you're getting it out the re-use queue it will still be used. That's good even if the table view is re-used because the cell types are the same type especially since you use the CellIdentifier to ensure that.

But, it's kind of odd that you're overlapping data. When you get a cell out of the re-use queue, how are you putting the data in it? Are you painting the data directly on the cell? Are you adding subViews with the data (causing multiple sets of overlapped data)? Typically, a cell contains subviews like text labels and the data is set on them so there's no scenario where data gets overlapped - the subviews of cell just has their data updated ...

Upvotes: 0

Related Questions