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
This is when I scroll down (look below)
After several scrolls Up and Down... (look below)
After several more scrolls... (look below)
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 wi开发者_开发技巧th different CellIdentifiers. That would make sure that the same cell does not get called.
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.
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.
One way that should fix this is to set all cells to nil in your cellForRowAtIndexPath
method. This makes sure that each is drawn freshly with no chance of something being overlayed like in your pictures. The downside is that it's extra work for the system, not being able to reuse cells like it wants to do
精彩评论