UITableViewCell图像重复

时间:2014-06-16 16:11:37

标签: ios objective-c uitableview

所以我在UINavigationController中有一个UITableViewController作为UITabBarController上的视图。除此之外,我的UITableView在每个部分都有多个部分和行,并且工作正常。在上一节中,我设置了cell.imageView.image属性,因为我想要一个小图片。现在的问题是,上面的部分有时(和随机)显示了它不应该的细胞图像。我附上了一个上部的截图,单元格不应该有图像。哦,在代码中,我有一个if语句检查单元格部分,如果不是最后一部分,则将图像视图图像设置为nil。 screenshot

PFQuery *query = [PFQuery queryWithClassName:@"Riot_API"];
    query.limit = 1;
    [query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
        @autoreleasepool {
            NSString *champInfoURL = [NSString stringWithFormat:@"https://prod.api.pvp.net/api/lol/static-data/na/v1.2/champion/%d?champData=all&api_key=%@", [[[[content objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] objectForKey:@"championId"] intValue], object[@"key"]];
            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:champInfoURL]];
            [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *champInfoData, NSError *connectionError) {
                @autoreleasepool {
                    NSURL *ddragonVersionURL = [[[NSURL URLWithString:@"http://ddragon.leagueoflegends.com/realms"] URLByAppendingPathComponent:[[NSUserDefaults standardUserDefaults] stringForKey:@"league_region"]] URLByAppendingPathExtension:@"json"];
                    NSURLRequest *ddragonVersionRequest = [NSURLRequest requestWithURL:ddragonVersionURL];
                    [NSURLConnection sendAsynchronousRequest:ddragonVersionRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *ddragonVersionResponse, NSData *ddragonVersionData, NSError *ddragonVersionConnectionError) {
                        if (!ddragonVersionConnectionError && ddragonVersionData) {
                            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
                                @autoreleasepool {
                                    NSDictionary *ddragonVersionDictionary = [[NSJSONSerialization JSONObjectWithData:ddragonVersionData options:kNilOptions error:nil] objectForKey:@"n"];
                                    NSURL *champIconServer = [NSURL URLWithString:[NSString stringWithFormat:@"http://ddragon.leagueoflegends.com/cdn/%@/img/champion", [ddragonVersionDictionary objectForKey:@"champion"]]];

                                    NSError *champInfoError;
                                    NSDictionary *champInfoJSON = [NSJSONSerialization JSONObjectWithData:champInfoData options:kNilOptions error:&champInfoError];
                                    NSDictionary *image = [champInfoJSON objectForKey:@"image"];

                                    NSURLRequest *champImageRequest = [NSURLRequest requestWithURL:[champIconServer URLByAppendingPathComponent:[image objectForKey:@"full"]]];

                                    [NSURLConnection sendAsynchronousRequest:champImageRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *imageData, NSError *connectionError) {
                                        if (imageData) {
                                            cell.imageView.image = [UIImage imageWithData:imageData];
                                            if (![self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
                                                if (indexPath.row == 0) {
                                                    @autoreleasepool {
                                                        CAShapeLayer *maskLayer = [CAShapeLayer layer];
                                                        maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:cell.imageView.bounds byRoundingCorners:UIRectCornerTopLeft cornerRadii:CGSizeMake(5, 5)].CGPath;
                                                        cell.imageView.layer.mask = maskLayer;
                                                        cell.imageView.layer.masksToBounds = YES;
                                                    }
                                                } else if (indexPath.row == [[content objectAtIndex:indexPath.section] indexOfObject:[[content objectAtIndex:indexPath.section] lastObject]]) {
                                                    @autoreleasepool {
                                                        CAShapeLayer *maskLayer = [CAShapeLayer layer];
                                                        maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:cell.imageView.bounds byRoundingCorners:UIRectCornerBottomLeft cornerRadii:CGSizeMake(5, 5)].CGPath;
                                                        cell.imageView.layer.mask = maskLayer;
                                                        cell.imageView.layer.masksToBounds = YES;
                                                    }
                                                }
                                            }
                                            [cell setNeedsLayout];
                                        }
                                    }];
                                }
                            });
                        }
                    }];
                }
            }];
        }
    }];
} else {
    cell.textLabel.text = [[[content objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] objectForKey:@"name"];
    cell.textLabel.textColor = nil;
    cell.detailTextLabel.text = nil;
    cell.imageView.image = nil;
}

1 个答案:

答案 0 :(得分:3)

好的,这里的问题(除了代码)是你有4个网络请求需要很长时间(不确定)。

<强>问题

滚动表格时,您会看到一行的单元格(例如cell A)(比如说row 4)。代码将触发并启动一系列下载最终会出现图像的内容。然后它将拍摄此图像并将其粘贴到cell A

但是,在执行此操作所花费的时间长度上,您现在已经滚动到一个新行(比如row 20)并且因为表格视图单元格的排队方式。 Row 20正在显示Cell A

所以你有问题。 Cell A现在显示row 20的文字,但显示row 4的图片。

这就是你遇到这个问题的原因。

可能的解决方案

最简单的解决方案是更改模型o下载不会直接进入单元格,而是进入模型对象(我认为Riot_API对象可能)。

这样你可以做这样的事情......

if (//riot object has image) {
    //show the image in the cell
} else {
    //tell the riot object to download its image
}

在骚乱对象中你会有这样的东西......

- (void)downloadImage
{
    if (self.alreadyDownloading) {
        // you only need to download once
        return;
    }

    //start the downloading chain.

    //when it finishes you can tell the table view controller
    //maybe through delegation
    //that the download finished...

    [self.delegate riotObjectFinishedImageDownload:self];
}