Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableViewCell Reusability causing Problems [with images] !

A picture is worth a thousand words, and I am guessing that the pictures posted below clearly convey the problem I am facing now.

Here's a little summary:

I create a tableView, and each tableViewCell has a textField as a subview. I scroll up and down, and my view gets messed up. I am guessing it is because of Cell Reusability. But I need help with this.

Note: This problem is not because of the buttons or the uitextView at the bottom of the screen. If I do not have them, and I have only the first three sections, the textFields get shifted and it messes up a the textFields of several cells. Also notice the textField shift in image 4 compared to other images. The code is pasted here http://www.pastie.org/2203340

**P.S.:**   I have added the solution to the problem at the end of the question. 

This is my normal view

enter image description here

This is when I scroll down (look below)

enter image description here

After several scrolls Up and Down... (look below) enter image description here

After several more scrolls... (look below) enter image description here

SOLUTION :

I really thank @caleb and others for pointing me in the right direction and helping me fixing this bug. For those people, whom are also facing the same problem, I thought I should provide a short and sweet answer.

Use UITableViewCells with different CellIdentifiers. That would make sure that the same cell does not get called.

like image 219
Legolas Avatar asked Jul 12 '11 19:07

Legolas


People also ask

What is a uitableviewcell?

The visual representation of a single row in a table view. A UITableViewCell object is a specialized type of view that manages the content of a single table row. You use cells primarily to organize and present your app’s custom content, but UITableViewCell provides some specific customizations to support table-related behaviors, including:

What are reusable cells in a table view?

Reusable cells are a fundamental piece of a working table view. Not only you need to understand how cells are reused by a table view, but you also need to design properly so that the table view will resize them automatically using Auto Layout. A table view displays its elements using specialized subviews called cells.

How to reload data from uitableviewcontroller?

Were you using a UITableViewController? One of the few things it does is call reloadData () on the table view. Now you have to do it yourself. Place it after you assign the data source to the table view.

What is the uitableviewdatasource protocol?

While a table view offers many sophisticated features, The UITableViewDataSource protocol has only two required methods. Implementing these two is enough to have a working table view. A UITableView instance calls these two methods to request the information it needs, piece by piece.


2 Answers

Your guess that it has to do with cell reuse is correct. The first thing I noticed is that you're using the same cell identifier for all your cells. That means that all cells are considered the same, and you should assume that everything about a cell will have to be configured every time. It'd be easier to use different identifiers for different types of cells, but I'll let you chew on that much for a bit...

Anyway, the root of your problem is this code:

if (section ==3){
    cell =nil;
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (indexPath.row ==0){
        cell.backgroundColor = [UIColor clearColor];
        cell.contentMode = UIViewContentModeScaleToFill;
        [cell.contentView addSubview:self.footerView];
    }
}

For this particular cell, you're setting the background color to clear, adding the footerView, etc. But you don't set the background color for any of the other cells, so as soon as this particular cell happens to be reused in a different position, you're going to get the clear background and other modifications in that position.

Now it'll probably be easier to see why you might want to use different cell identifiers for different types of cells. If you use a different identifier for your clear cells than you do for your white ones, you don't have to worry about clear cells being recycled as white cells and vice versa. You should use a different identifier for each "cell type", where "cell type" is defined by all the cell attributes that you don't want to have to configure each time you reuse a cell.

You're doing a lot of work in your -reuseTableViewCellWithIdentifier:withIndexPath: method that ends up making the cells not very reusable. Instead, you should identify each different "type" or "style" of cell that you want to display independant of the particular information that's displayed in them. For example, all the cells in your first three sections appear to be about the same: they're all similar to the UITableViewCellStyleValue1 standard cell style, except that the detail label is left empty and a text field is added to the right side. Use the same reuse identifier for all these cells, then. -reuseTableViewCellWithIdentifier:withIndexPath: really shouldn't care about the index path -- it should just create and return a cell in the required style as determined by the supplied reuse identifier. Leave the work of setting the text of the fields in those cells to the -tableView:cellForRowAtIndexPath: method.

I notice that you're storing the index path and a pointer to the text field when you create each cell. Neither of these is going to help at all if you're reusing cells.

If you're never going to add more cells to the table than the ones you've shown, it may be simpler for you to simply skip the whole reuse thing. Reusing cells gives a marked performance improvement when scrolling through a table with dozens or hundreds of cells, but if you'll never have more than ten or fifteen cells, and half of those are on the screen at any given time, the advantage of reusing cells isn't that great. Nevertheless, I'd encourage you to spend the time to get your head around the idea; sooner or later you're going to want to create a table with many rows.

like image 72
Caleb Avatar answered Sep 22 '22 17:09

Caleb


I've experienced this before too. Try creating a new cell for each type. This way cells that contain text fields aren't reused for the title only cells.

like image 27
Brandon Schlenker Avatar answered Sep 19 '22 17:09

Brandon Schlenker