所以我在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;
}
答案 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];
}