Ghobs
Ghobs

Reputation: 859

Reloading UITableView causes incorrect setting of labels

When my UITableView loads for the first time, everything in the code below functions correctly. However, if it reloads for whatever reason (refresh, etc.), it starts assigning a cell.bestMatchLabel.text value of @"Best Match" to random cells, rather than only the first one as I specified in the code. Why is calling reload on my table causing the below code to not run correctly?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //load top 3 data
    NSDictionary *currentSectionDictionary = _matchCenterArray[indexPath.section];
    NSArray *top3ArrayForSection = currentSectionDictionary[@"Top 3"];

    // if no results for that item
    if (top3ArrayForSection.count-1 < 1) {

        // Initialize cell
        static NSString *CellIdentifier = @"MatchCenterCell";
        EmptyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell) {
            // if no cell could be dequeued create a new one
            cell = [[EmptyTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }

        // title of the item
        cell.textLabel.text = @"No items found, but we'll keep a lookout for you!";
        cell.textLabel.font = [UIFont systemFontOfSize:12];

        cell.detailTextLabel.text = [NSString stringWithFormat:@""];
        [cell.imageView setImage:[UIImage imageNamed:@""]];

        return cell;
    }

    // if results for that item found
    else {

        // Initialize cell
        static NSString *CellIdentifier = @"MatchCenterCell";
        MatchCenterCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell) {
            // if no cell could be dequeued create a new one
            cell = [[MatchCenterCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }

        tableView.separatorColor = [UIColor clearColor];

        if (indexPath.row == 0) {
            cell.bestMatchLabel.text = @"Best Match";
            cell.bestMatchLabel.font = [UIFont systemFontOfSize:12];
            cell.bestMatchLabel.textColor = [UIColor colorWithRed:0.18 green:0.541 blue:0.902 alpha:1];

            [cell.contentView addSubview:cell.bestMatchLabel];
        }


        // title of the item
        cell.textLabel.text = _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Title"];
        cell.textLabel.font = [UIFont systemFontOfSize:14];

        // price + condition of the item
        NSString *price = [NSString stringWithFormat:@"$%@", _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Price"]];
        NSString *condition = [NSString stringWithFormat:@"%@", _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Item Condition"]];

        cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ - %@", price, condition];
        cell.detailTextLabel.textColor = [UIColor colorWithRed:0.384 green:0.722 blue:0.384 alpha:1];

        // Load images using background thread to avoid the laggy tableView
        [cell.imageView setImage:[UIImage imageNamed:@"Placeholder.png"]];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            // Download or get images here
            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Image URL"]]];

            // Use main thread to update the view. View changes are always handled through main thread
            dispatch_async(dispatch_get_main_queue(), ^{
                // Refresh image view here
                [cell.imageView setImage:[UIImage imageWithData:imageData]];
                cell.imageView.layer.masksToBounds = YES;
                cell.imageView.layer.cornerRadius = 2.5;
                [cell setNeedsLayout];
            });
        });
        return cell;
    }

}

Upvotes: 0

Views: 255

Answers (1)

Mahmoud Adam
Mahmoud Adam

Reputation: 5852

That is because table dequeue same cell for multiple indexes as you scroll down, so you need to add else statement in the following code

if (indexPath.row == 0) {
        cell.bestMatchLabel.text = @"Best Match";
        cell.bestMatchLabel.font = [UIFont systemFontOfSize:12];
        cell.bestMatchLabel.textColor = [UIColor colorWithRed:0.18 green:0.541 blue:0.902 alpha:1];

        [cell.contentView addSubview:cell.bestMatchLabel];
    [cell.bestMatchLabel setHidden:NO];
} else {
    [cell.bestMatchLabel setHidden:YES];
}

but a better approach for this case is to use different cell identifier for that row and only add the bestMatchLabel once when first creating the cell

Upvotes: 1

Related Questions