DoS
DoS

Reputation: 1474

how to fix an issue with custom subclass of uitableviewcell reuse?

Before I get crucified for this, let me state... Yes, I have read every "relevant" answer on this topic and have not found a workable solution. Most "correct" answers are pre-ARC and discuss "releasing" a cell, which just isn't done anymore. Secondly, my problem is not "global", meaning some views have no problems, while others do. So here is my question...

I have sub-classed uitableviewcell and setup some uilabels & custom uiviews. From there I wired everything up in ib (Xcode 5.x iOS 7.x). Once I put in the appropriate code and create the tableview & dynamic cells from a nsarray "not mutable" everything works exactly as expected with no issues.

This is the fun part. I am making changes to allow the data source of the tableview, which is an nsarray to be mutable to allow adding and removing of items / cells. This is where things get hairy. When I start to add more objects to the array and when the reuse cell is being put on screen visual data from old cells is being reused on new cells. I say "visual" because once the cell is selected the view updates to display the correct information. The part that is interesting is that as I stated I have some uilabels which never have any problems being redisplayed, my custom views however are now the piece of the puzzle that is displaying info from past cells, and when scrolling back up, the original cells no longer display the correct information. Once the cell is tapped, then the cell updates and displays the correct information.

the most confusing bit of this is that before my array was mutable and had a static amount of objects this worked fine. Even if a cell went off screen and came back, it was still the correct information being displayed. Now I know that shouldn't have anything to do with it, but it is strange that it worked using the same tableview & cell code that I am using now.

I have tried adding in

MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

if (!cell) {
     cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; // note: obviously as stated, tacking on "autorelease" here as mention in other suggestions is not going to work.
}

Which doesn't fix the issue.

I tried overriding the "prepareForReuse" method on my custom cell subclass and that does not resolve the issue either. I have made the views, "strong" & "weak", and all that and still every 3rd or so cell gets repeated with garbage data until it is refreshed. Again, the uilabels which are setup the same way as the views have no problems and data is never reused. I would say there is a problem with my custom views, but setting up the table from a static source of identical information there is no problem.

I would like to post some code, but it's all pretty generic code for tableviews & delegates. any suggestions would be greatly appreciated.

As i said the code is all pretty generic, but apparently it needs posing anyway so here it is..

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    MyThing *thing = self.stuffArray[indexPath.row];

    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    cell.thisLabel.text = thing.someText;
    cell.thatLabel.text = thing.otherText;

    cell.view1.someProptery = thing.object1.property
    cell.view2.someProptery = thing.object2.property
    cell.view3.someProptery = thing.object3.property 
    //"someProperty" on "view..." is an NSInt that is used to determine custom drawing in the view.

    return cell;
}

Upvotes: 0

Views: 1246

Answers (1)

danh
danh

Reputation: 62686

I think the key to the solution lies in your comment about the custom views in the cells. If cellForRowAtIndexPath is altering the states of those views, they need to know that they must be redrawn, so you'll need to augment the synthesized setter in your custom view.m that has someProperty.

If the someProperty determines how this view get's drawn, then it's incumbent upon the setter to indicate that the view is out of date....

- (void)setSomeProperty:(NSInteger)someInt {
    _someProperty = someInt;
    [self setNeedsDisplay];
}

Upvotes: 1

Related Questions