views:

315

answers:

2

Hi all, i would to have alternate 2 colors of rows, like the first black, the second white, the third black, etc, etc...

my approach is like a basic exercise of programming to calculate if a number is odd number or not:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
cell = ((MainCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]);
if (cell==nil) {

    NSArray *topLevelObjects=[[NSBundle mainBundle] loadNibNamed:@"MainCell"    owner:self options:nil];

    for (id currentObject in topLevelObjects){
        if ([currentObject isKindOfClass:[UITableViewCell class]]){
            if ((indexPath.row % 2)==0) {
                [cell.contentView setBackgroundColor:[UIColor purpleColor]];

            }else{
                [cell.contentView setBackgroundColor:[UIColor whiteColor]];

            }
            cell =  (MainCell *) currentObject;
            break;
        }
    }

}else {

    AsyncImageView* oldImage = (AsyncImageView*)
    [cell.contentView viewWithTag:999];
    [oldImage removeFromSuperview];
}return cell;

The problem is that when i do a rapid scroll, the background of cells become like the last 2 cell black, the first 2 cell white or something like this, but if i scroll slow works fine. I think the problem is the cache of reusableCell.

Any ideas?

TIA

+3  A: 

Cells get recycled (that is what you are doing when you dequeue them and check if it is nil). So instead of setting the background color when you create the cell, set it sometime after. So:

if( !cell ) {
  // create the cell and stuff
}
if( [indexPath row] % 2)
  [cell setBackgroundColor:[UIColor whiteColor]];
else
  [cell setBackgroundColor:[UIColor purpleColor]];
Jason Coco
OK, works very fine..!
Mat
+2  A: 

What I believe is happening is that when you dequeue a reusable cell, you do not do so in a defined order. As it would happen, when you scroll slowly, cells become available one at a time, and dequeued to you, in order. When you scroll quickly, the order becomes undefined, as does the order in which they are dequeued. I believe this is why (in large part) apple designed the UITableView API to dequeue by identifier - so you could reuse different types of cells, such as those with different colors, easily. As such, I recommend modifying the code to have each cell color have its own identifier. (Furthermore, if possible have an outlet connecting this tableview datasource to the cell directly, or save it in an ivar after loading it once, and then copy it rather than cycling through high level objects)

Jared P
Don't do this. If you are just changing the background color, it is like cell content, so use the same identifier. You would use different identifiers if you had different cell arrangements or something. You waste resources by using different identifiers for something like this.
Jason Coco
Like 2 nib files with 2 different identifier?
Mat
@Mat: You would use different identifiers if you had different layouts for your cells. So yes, if you had two nibs that you loaded based on content that were totally different. In that case, you don't want to accidentally get the wrong kind of cell back. But you don't use this for simple changes like background color or whatever.
Jason Coco
In this particular case, you would only be loading at most an extra two cells over the lifespan of the table, so it wouldn't be an atrocious cost. Furthermore, it is only after my recommendation that the cell is loaded differently (not from the nib) that would make this acceptable, as it would lower the cost of creation tremendously. That being said, your answer is absolutely better.
Jared P