很长时间在UITableCellView中从Web加载图片

时间:2015-02-02 08:47:39

标签: ios objective-c uitableview

在我的应用中,我正在阅读一个文件,其中存储了一些URL到图片。我将介绍如下照片:

enter image description here

为了做到这一点,我写了下面的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"HistoryCell";
    HistoryCustomCell *historyCustomCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    historyCustomCell.labelTitle.text = [sortedArray[indexPath.row] objectForKey:@"title"];
    historyCustomCell.labelContent.text = [sortedArray[indexPath.row] objectForKey:@"text"];
    if ([[sortedArray[indexPath.row] objectForKey:@"date"]isEqualToString:stringDate]) {
        historyCustomCell.labelDate.text = [[sortedArray[indexPath.row] objectForKey:@"time"] stringByReplacingOccurrencesOfString:@" " withString:@""];
    } else {
        historyCustomCell.labelDate.text = [sortedArray[indexPath.row] objectForKey:@"date"];
    }

    if (![[sortedArray[indexPath.row] objectForKey:@"imgUrl"] isEqualToString:@""]) {
        CALayer *cellImageLayer = historyCustomCell.imageView.layer;
        [cellImageLayer setCornerRadius:33.5];
        [cellImageLayer setMasksToBounds:YES];

        if ([[NSString stringWithFormat:@"%@",[sortedArray[indexPath.row]objectForKey:@"suggested"] ] isEqualToString:@"1"] && [[NSString stringWithFormat:@"%@",[sortedArray[indexPath.row]objectForKey:@"breakingNews"] ] isEqualToString:@"0"]) {
            // SUGGESTED
            [cellImageLayer setBorderColor:[[UIColor colorWithRed:161.0 green:199.0 blue:0 alpha:1.0] CGColor]];
            [cellImageLayer setBorderWidth:3.0];
        }
        if ([[NSString stringWithFormat:@"%@",[sortedArray[indexPath.row]objectForKey:@"breakingNews"] ] isEqualToString:@"1"] && [[NSString stringWithFormat:@"%@",[sortedArray[indexPath.row]objectForKey:@"suggested"] ] isEqualToString:@"0"]) {
            // BREAKING NEWS
            [cellImageLayer setBorderColor:[[UIColor colorWithRed:254.0 green:214.0 blue:0 alpha:1.0] CGColor]];
            [cellImageLayer setBorderWidth:3.0];
        }
        if ([[sortedArray[indexPath.row] objectForKey:@"is_unread"] intValue] == 1) {
            historyCustomCell.contentView.superview.backgroundColor = [UIColor whiteColor];
        } else {
            historyCustomCell.contentView.superview.backgroundColor = [UIColor colorWithRed:239.0/255.0 green:239.0/255.0 blue:239.0/255.0 alpha:1.0];
        }

        NSURL *imgUrl = [NSURL URLWithString:[sortedArray[indexPath.row] objectForKey:@"imgUrl"]];
        UIImage *imgThumb = [UIImage imageWithData:[NSData dataWithContentsOfURL:imgUrl]];
        CGSize itemSize = CGSizeMake(67, 67);
        UIGraphicsBeginImageContext(itemSize);
        CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
        [imgThumb drawInRect:imageRect];
        historyCustomCell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    } else {
        [historyCustomCell.imageView setImage:nil];
    }

    return historyCustomCell;
}

当  我尝试在设备上运行应用程序,视图将像图像一样绘制,但加载图片需要太多,而UITableView滚动速度非常慢。我想这是一个问题,因为接收图像的连接,我如何解决它?

更新 我想我可以使用这种方法来解决我的问题:

- (void) loadImageFromWeb:(NSURL *)urlImg andImageView:(UIImageView *)imageView {
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:urlImg];

    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse * response,
                                               NSData * data,
                                               NSError * error) {
                               if (!error){
                                   UIImage *imgThumb = [UIImage imageWithData:data];
                                   CGSize itemSize = CGSizeMake(50, 50);
                                   UIGraphicsBeginImageContext(itemSize);
                                   CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
                                   [imgThumb drawInRect:imageRect];
                                   imageView.image = UIGraphicsGetImageFromCurrentImageContext();
                                   UIGraphicsEndImageContext();
                                   [hud hide:YES];
                               } else {
                                   NSLog(@"ERRORE: %@", error);
                                   [hud hide:YES];
                               }

                           }];
}

使用这种方法,它应该在GUI上加载UIImageView而不会延迟吗?

2 个答案:

答案 0 :(得分:0)

UIImage *imgThumb = [UIImage imageWithData:[NSData dataWithContentsOfURL:imgUrl]];

上面的一行是同步通话。这意味着在该行完成从服务器下载所有数据并将其转换为UIImage之前,其余代码将不会运行。你想要做的是一个异步请求。

您可以搜索如何执行异步URL请求。通常这涉及委托模式或完成块,它将在图像下载完成后执行。这将允许其余代码运行,并且应用程序的UI不会冻结。

答案 1 :(得分:0)

这是问题

UIImage *imgThumb = [UIImage imageWithData:[NSData dataWithContentsOfURL:imgUrl]];

来自文档

  

<强> dataWithContentsOfURL

     

此方法非常适合将data:// URL转换为NSData对象,   并且还可以用于同步读取短文件。不使用   这种同步方法可以请求基于网络的URL。对于   基于网络的URL,此方法可以阻止当前线程为数十   慢速网络上的秒数,导致用户体验不佳,以及   在iOS中,可能会导致您的应用被终止。

要下载图像并且仍然具有平滑的滚动行为,您需要下载图像异步。在您的情况下,发生的是主线程上的执行被阻止,直到下载图像。为避免这种情况,您必须在单独的线程上下载图像,并在完成下载后获取UIImage对象并将其设置为各自的单元格。

有很多方法可供下载。很老的方法是使用NSOperations,或者文档建议使用dataTaskWithURL:completionHandler代替dataWithContentsOfURL

如果您使用的是AFNetworking,则它有一个甜蜜的UIImageView类别。只需包含该内容并致电

[historyCustomCell.imageView setImageWithURL:imgUrl]

这将以异步方式下载并缓存图像。