4

I've subclassed the UITableViewCell to add custom appearance to it. At the init level of the MYTableViewCell I added 4 subviews: UIImageView, and three UILabel(s). All 4 subviews have a different Tag assigned to them.

Inside the cellForRowAtIndexPath method I either create a new cell if it wasn't available at first, or reuse available one and assign the proper text to the ui labels.

The problem I am having is that if I try to scroll super fast, then the data gets messed up, however if I scroll up and down more slowly, then everything works fine.

Any thoughts??

Below is the code:

- (MyTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"itemListTableViewCell";
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

DisplayableEntity *displayableEntity = [self.fetchedResultsController objectAtIndexPath:indexPath];

if( ! cell ) {
    cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    [self tableView:tableView appearanceForCell:cell withEntity:displayableEntity];
} else {

    UIImageView *imageView = (UIImageView *) [cell viewWithTag:IMAGEVIEW_TAG];
    imageView.image = [UIImage imageNamed:displayableEntity.displayImageName];

    UILabel *titleLabel = (UILabel *) [cell viewWithTag:TITLEVIEW_TAG];
    titleLabel.text = displayableEntity.entityName;

    UILabel *itemDescription = (UILabel *) [cell viewWithTag:DESCRIPTION_TAG];
    itemDescription.text = displayableEntity.entityDesctiption;
  }
}

// some code removed to make it brief
- (void)tableView:(UITableView *)tableView appearanceForCell:(MyTableViewCell *)cell withEntity:(DisplayableEntity *)entity {

    // cell image view
    UIImageView *cellImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[entity displayImageName]]];
    [cellImageView setTag:IMAGEVIEW_TAG];
    [cell addSubview:cellImageView];

    // adding entity name label    
    UILabel *itemTitleName = [self itemTitleNameLabelWithFrame:itemNameLabelRect itemName:[entity entityName]];
    [itemTitleName setTag:TITLEVIEW_TAG];
    [cell addSubview:itemTitleName];

    // adding 'assigned to' label right under the item name label
    UILabel *itemDescriptionLabel = [self itemDescriptionLabelWithFrame:descriptionLabelFrame itemDescription:[entity entityDesctiption]];
    [itemDescriptionLabel setTag:DESCRIPTION_TAG];
    [cell addSubview:itemDescriptionLabel];
}
ymotov
  • 1,449
  • 3
  • 17
  • 28

1 Answers1

3

I see some troubles in tableView:cellForRowAtIndexPath: logic It should be:

  1. Dequeue cell
  2. If cell cannot be dequeued - create the new one
  3. Set all cell properties

I mean something like this:

- (MyTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *CellIdentifier = @"itemListTableViewCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    } // <-- Note there is no else, we should reset properties in both cases

    NSManagedObject *managedObject = [_fetchedResultsController objectAtIndexPath:indexPath];

    cell.textLabel.text = [managedObject valueForKey:@"text"];
    cell.imageView.image = [managedObject valueForKey:@"image"];

    return cell;
}
voromax
  • 3,369
  • 2
  • 30
  • 53
  • Thanks! Not sure why, but that solved the problem for me. Inside my if clause I did set the cell properties along with the cell appearance and somehow that was really messing everything up. Once I removed that, also removed the else clause and only set properties in one place as you have in your example... then everything magically worked. So thanks again. – ymotov Sep 04 '12 at 01:55
  • setting all the data for all the conditions did the trick for me , thanks – vishal dharankar Feb 07 '18 at 19:02