Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective - C: UITableView Content Changing on Scroll

I'm using the QuickBlox Framework to build a chatting application. Currently, when the chat view opens up, everything looks great.

However, when the users begins to scroll up and down the chat history, some of the cells begin to change (for example, they'll show an image which should be placed in a different row).

Below is my code for cellForRowAtIndexPath, if anyone can tell me what I'm doing wrong

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

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

    if (message.attachments.count > 0) {

        ImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ImageCellIdentifier];

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

        return cell;

    } else {

        ChatMessageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ChatMessageCellIdentifier];

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

        return cell;
    }

}

EDIT Please see below my ImageTableViewCell configureCellWithImage method:

- (void) configureCellWithImage:(QBChatMessage*)message {

    NSString *time = [message.dateSent timeAgoSinceNow];

    if ([QBSession currentSession].currentUser.ID == message.senderID) {

    // Message was sent by me

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

        if (imageData) {

        // image is already downloaded

            dispatch_async(dispatch_get_main_queue(), ^{

            UIImage *image = [UIImage imageWithData:imageData];
            UIImageView *cellImage = [[UIImageView alloc] init];

            [self.backgroundImageView setFrame:CGRectMake(320-155, 10, 140, 140)];

            cellImage.frame = CGRectMake(7, 7, 120, 120);
            [cellImage setContentMode:UIViewContentModeScaleAspectFill];

            cellImage.clipsToBounds = YES;
            cellImage.layer.cornerRadius = 5;
            cellImage.image = image;

            self.backgroundImageView.image = aquaBubble;
            [self.backgroundImageView addSubview:cellImage];
            [self.contentView addSubview:self.backgroundImageView];

            });
        } else {

    // downloads the image and displays as above

    }

    } else {

    // Message was sent by another user

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

        if (imageData) {

            dispatch_async(dispatch_get_main_queue(), ^{

            UIImage *image = [UIImage imageWithData:imageData];
            UIImageView *cellImage = [[UIImageView alloc] init];

            [self.backgroundImageView setFrame:CGRectMake(padding/2, padding+5, 140, 140)];

            cellImage.frame = CGRectMake(13, 7, 120, 120);
            [cellImage setContentMode:UIViewContentModeScaleAspectFill];
            cellImage.layer.cornerRadius = 5;
            cellImage.clipsToBounds = YES;
            cellImage.image = image;

            self.timeLabel.frame = CGRectMake(20, self.backgroundImageView.frame.size.height + 20, 80, 20);
            self.timeLabel.text = [NSString stringWithFormat:@"%@", time];
            [self.timeLabel setFont:[UIFont systemFontOfSize:10.0]];
            [self.timeLabel setTextColor:[UIColor blackColor]];

            [self.contentView addSubview:self.timeLabel];

            self.nameAndDateLabel.textAlignment = NSTextAlignmentLeft;

            QBUUser *sender = [ChatService shared].usersAsDictionary[@(message.senderID)];

            NSInteger loginForColor = [sender.login integerValue];
            loginForColor = loginForColor % 255;

            self.nameAndDateLabel.text = [NSString stringWithFormat:@"%@", sender.fullName];

            self.backgroundImageView.image = orangeBubble;
            [self.backgroundImageView addSubview:cellImage];
            [self.contentView addSubview:self.backgroundImageView];

            });

        } else {

          // downloads the image and displays as above
        }

    }
}
like image 955
Adam G Avatar asked Sep 08 '15 18:09

Adam G


1 Answers

Cells get reused. Therefore you must always set/reset all properties of the cell each time.

For every if statement that sets a cell's property, there must be an else statement that resets the same property - even if it just clears the value.

Also you must avoid adding subviews over and over each time the cell is used. You have code that creates and adds an image view to the cell. But you keep adding new image views over and over. Just add it once if needed. If it's already there, update it with the new image instead of adding a new one.

like image 106
rmaddy Avatar answered Oct 23 '22 05:10

rmaddy