Adam G
Adam G

Reputation: 1188

Custom TableViewCells Not Being Reused

My chat application uses the following cellForRowAtIndexPath to setup the chat dialog history for the user:

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

{

QBChatMessage *message = [[ChatService shared] messagsForDialogId:self.dialog.ID][indexPath.row];

    if (message.attachments.count > 0) {

        ImageTableViewCell *cell = [[ImageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ImageCellIdentifier message:message];

    [cell fillWithStickerMessage:message];
    cell.backgroundColor = [UIColor whiteColor];

    }

return cell;

}

Here is the init method in my ImageTableViewCell.m file.

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier message:(QBChatMessage *)message  {

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self) {

        NSData *imageData = [FTWCache objectForKey:[NSString stringWithFormat:@"%@", [message.attachments[0] valueForKey:@"ID"]]];

        if (imageData) {

            UIImage *image = [UIImage imageWithData:imageData];
            [self.cellImage setImage:image];

        } else {

            for(QBChatAttachment *attachment in message.attachments){
                // download file by ID

                [QBRequest TDownloadFileWithBlobID:[attachment.ID integerValue] successBlock:^(QBResponse *response, NSData *fileData) {

                    [FTWCache setObject:fileData forKey:[NSString stringWithFormat:@"%@", attachment.ID]];

                    UIImage *image = [UIImage imageWithData:imageData];
                    [self.cellImage setImage:image];

                } statusBlock:^(QBRequest *request, QBRequestStatus *status) {
                    // handle progress
                } errorBlock:^(QBResponse *response) {
                    NSLog(@"error: %@", response.error);
                }];
            }
        }

        self.nameAndDateLabel = [[UILabel alloc] init];
        self.timeLabel = [[UILabel alloc] init];
        self.cellImage = [[UIImageView alloc] init];

        self.cellImage.opaque = YES;

        if ((IS_IPHONE_4) || (IS_IPHONE_5)){
            [self.nameAndDateLabel setFrame:CGRectMake(20, 5, 300, 20)];
        } else if (IS_IPHONE_6) {
            [self.nameAndDateLabel setFrame:CGRectMake(20, 5, 355, 20)];
        } else if (IS_IPHONE_6_PLUS) {
            [self.nameAndDateLabel setFrame:CGRectMake(20, 5, 394, 20)];
        }

        [self.nameAndDateLabel setFont:[UIFont boldSystemFontOfSize:15]];
        [self.nameAndDateLabel setTextColor:[UIColor lightGrayColor]];
        [self.contentView addSubview:self.nameAndDateLabel];

        self.backgroundImageView = [[UIImageView alloc] init];
        [self.backgroundImageView setFrame:CGRectZero];
        [self.backgroundImageView addSubview:self.cellImage];
        [self.contentView addSubview:self.backgroundImageView];

    }

    return self;

}

The problem is that when scrolling through the table view, the cells are constantly initialized in initWithStyle in the ImageViewCell.m file. Shouldn't that only happen if the cell hasn't been created already? What am I doing wrong?

Upvotes: 0

Views: 27

Answers (1)

onnoweb
onnoweb

Reputation: 3038

You're missing a call in cellForRowAtIndexPath to

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
                           forIndexPath:(NSIndexPath *)indexPath

or

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier

depending on whether you registered your UITableViewCell nib or class.

So for example in cellForRowAtIndexPath you would do:

ImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ImageCellIdentifier];
if (cell == nil) {
    cell = [[ImageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ImageCellIdentifier message:message];
}

Upvotes: 1

Related Questions