简体   繁体   English

iOS:滚动时UITableView单元格混杂

[英]iOS: UITableView cells gets mixed up while scrolling

I am facing one issue regarding UITableView cells get mixed up while scrolling, specially for images. 我面临一个有关UITableView单元在滚动时混合在一起的问题,特别是对于图像。

I am not sure why this is going one. 我不确定为什么会这样。
I have change the patter for displaying then also its get mixed up. 我更改了显示的模式,然后将其混淆了。
Below is my code. 下面是我的代码。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"FriendsCell";
    FriendsTableCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"FriendsTableCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    FriendsTableCell *simpleTableCell = (FriendsTableCell *)cell;

    _model = [_contentArray objectAtIndex:indexPath.row];

    simpleTableCell.nameLabel.text = _model.fullname;

    if(_friendsSegmentControl.selectedSegmentIndex == 0) {

        simpleTableCell.followButton.hidden = NO;
        simpleTableCell.removeButton.hidden = NO;
        simpleTableCell.unBlockButton.hidden = YES;
        simpleTableCell.ignoreRequest_btn.hidden = YES;
        simpleTableCell.rejectRequest_btn.hidden = YES;
        simpleTableCell.acceptRequest_btn.hidden = YES;

        simpleTableCell.removeButton.tag = indexPath.row;
        [simpleTableCell.removeButton addTarget:self action:@selector(deleteFriend_btn:) forControlEvents:UIControlEventTouchUpInside];

        simpleTableCell.followButton.tag = indexPath.row;

        if([_model.isfollowed isEqualToString:@"YES"]) {
            [simpleTableCell.followButton setImage:[UIImage imageNamed:@"follow_yellow.png"] forState:UIControlStateNormal];
            [simpleTableCell.followButton addTarget:self action:@selector(unfollowFriend_btn:) forControlEvents:UIControlEventTouchUpInside];
        }
        else {
            [simpleTableCell.followButton setImage:[UIImage imageNamed:@"follow_white.png"] forState:UIControlStateNormal];
            [simpleTableCell.followButton addTarget:self action:@selector(followFriend_btn:) forControlEvents:UIControlEventTouchUpInside];
        }
    }

    NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,(__bridge CFStringRef) _model.prof_pic,NULL,(CFStringRef)@"!*'();:@&=+$,/?%#[]",kCFStringEncodingUTF8));

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^(void) {

        NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.touristtube.com/%@",escapedString]]];
        UIImage *image = [UIImage imageWithData:imageData];
        dispatch_async(dispatch_get_main_queue(), ^{
            simpleTableCell.profileImageView.image = image;
        });
    });

}

Two things you need to ensure while creating cells for table view- 为表格视图创建单元格时需要确保的两件事:

1) Regarding reusable cells - As you are using reusable cells, so in case if it's dequeued it will show the data for the index path for which it was originally created. 1) 关于可重用单元格 -当您正在使用可重用单元格时,以防万一它出队了,它将显示最初为其创建的索引路径的数据。

It's right that you are updating each cell(whether newly created/ dequeued) with the data for the corresponding index path just before displaying it in 正确的是,在显示之前,要使用相应索引路径的数据更新每个单元(无论是新创建的还是已出队的)

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

Also you can update the data for each cell' container for corresponding index path in 您也可以为每个单元格容器中的相应索引路径更新数据

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

as well. 也一样

So, please ensure if the cell is reused you should update the data of each container(cell's subviews) with the data for the current index path. 因此,请确保如果单元格被重用,则应使用当前索引路径的数据更新每个容器(单元格的子视图)的数据。 Doing so will resolve your issue of cell's content getting overlapped. 这样做可以解决单元格内容重叠的问题。

2) Regarding asynchronously downloading the images for cells - Also as you are downloading the images asynchronously, so it will not block the main thread and as soon as the image is downloaded you need to switch to main thread to set the image to the cell. 2) 关于异步下载单元格的图像 -同样,由于要异步下载图像,因此它不会阻塞主线程,并且一旦下载图像,您就需要切换到主线程以将图像设置为单元格。

Now the thing to remember in case of asynchronous image downloading is that you should always access the cell for the correct index path on main thread and set the downloaded image to the cell's image view for the index path for which it was scheduled to be downloaded. 现在,在异步映像下载的情况下要记住的事情是,您应始终访问主线程上正确索引路径的单元,并将下载的映像设置为计划为其下载索引路径的单元的映像视图。

So for the images you should update your image downloading method as 因此,对于图像,您应该将图像下载方法更新为

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^(void) {

        NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.touristtube.com/%@",escapedString]]];
        UIImage *image = [UIImage imageWithData:imageData];
        dispatch_async(dispatch_get_main_queue(), ^{
           FriendsTableCell *cell = [tableView cellForRowAtIndexPath:indexPath];
            cell.profileImageView.image = image;
            [cell setNeedsLayout];
        });
    });

this will resolve your issue of cell's image intended to be displayed for a index path but actually showing on a cell at some other index path. 这将解决您要为索引路径显示但实际上在其他索引路径上的单元格上显示的单元格图像的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM