iOS延迟加载表格图像

Ram*_*ain 10 lazy-loading objective-c uitableview uiscrollview ios

我一直在使用苹果提供的示例中成功实施的图像延迟加载在我的应用在这里.问题是,我想在我滚动时加载图像,但只有当我完成拖动时才将图像加载到单元格中(从屏幕释放我的手指.此时单元格保持为空).我修改了代码如下:

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

    //NSLog(@"cell for row at indexpath, size - %f, current - %d", flowTable.contentSize.height, self.current);

    NSString *CellIdentifier = @"FlowCell";

    MyFlowCell *cell = (MyFlowCell *)[self.flowTable dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"FlowCell" owner:nil options:nil];
       // cell = [nib objectAtIndex:0];

        for(id currentObject in nib)

        {

        if([currentObject isKindOfClass:[MyFlowCell class]])

        {
            cell = (MyFlowCell *)currentObject;

            break;
        }
        }
    }

    ImageDetails *rowItem = [self.imageData objectAtIndex:indexPath.row];

    if (!rowItem.mainImage)
    {  
       // if (self.flowTable.dragging == NO && self.flowTable.decelerating == NO)
       // {

            [self startIconDownload:rowItem forIndexPath:indexPath];

        //}

        cell.mainImage.backgroundColor = [UIColor grayColor];

    }
    else
    {

            cell.mainImage.image = rowItem.mainImage;

    }
    }


    return cell;
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
    {
      //  [self loadImagesForOnscreenRows];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    //[self loadImagesForOnscreenRows];
}
Run Code Online (Sandbox Code Playgroud)

此外,我发现在我的ImageDownloader类中,NSURLConnection甚至都没有收到响应,直到我从屏幕上释放手指.我一直试图找出为什么会这样,但到目前为止我还没有成功.如果我错过了什么,请告诉我.

Rob*_*Rob 9

更新的答案:

标准的Apple LazyTableImages存在一些缺陷:

  1. 在滚动完成之前,它不会尝试检索图像.我明白为什么他们选择这样做(可能不想检索可能会滚动的图像),但这会导致图像显得比必要的慢.

  2. 它不会将并发请求的数量限制为某个合理的数量.是的,NSURLConnection会自动冻结请求,直到请求的最大数量降到一些合理的数量,但在最坏的情况下,您实际上可以让请求超时,而不是简单地排队.

  3. 一旦开始下载图像,即使单元格随后滚出屏幕,它也不会取消它.

简单的解决方法是退出IconDownloader和所有滚动/减速逻辑,只使用或UIImageView来自的任何一个类别.SDWebImageAFNetworking

如果您要自己解决这个问题,那么需要做一些工作才能完成所有这些工作.但这里是LazyTableImages的再现,用于NSOperationQueue确保我们(a)限制并发请求; (b)允许我们取消请求.我承认我更喜欢上面的UIImageView类别实现,更好,但我试图继续使用Apple的原始结构LazyTableImages,同时弥补我上面列举的缺陷.


Wol*_*ine 8

您可以按照以下步骤在tableview中实现延迟加载:

在你的Class.h中,放:

NSMutableDictionary *Dict_name;
BOOL isDragging_msg, isDecliring_msg;
Run Code Online (Sandbox Code Playgroud)

现在在Class.m文件中,将此代码放入视图中加载:

Dict_name = [[NSMutableDictionary alloc] init];
Run Code Online (Sandbox Code Playgroud)

在cellForRowAtIndexPath中:

if ([dicImages_msg valueForKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"image name or image link"]]) { 
    cell.image_profile.image=[dicImages_msg valueForKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"image name or image link"]];
}
else
{
    if (!isDragging_msg && !isDecliring_msg)
    {
        [dicImages_msg setObject:[UIImage imageNamed:@"Placeholder.png"] forKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"image name or image link"]];
        [self performSelectorInBackground:@selector(downloadImage_3:) withObject:indexPath];
    }
    else
    {
        cell.image_profile.image=[UIImage imageNamed:@"Placeholder.png"];
    }
}
Run Code Online (Sandbox Code Playgroud)

对于下载图像,该功能是:

-(void)downloadImage_3:(NSIndexPath *)path{
    NSAutoreleasePool *pl = [[NSAutoreleasePool alloc] init];

    NSString *str=[here Your image link for download];

    UIImage *img = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:str]]]; 

    [dicImages_msg setObject:img forKey:[[msg_array objectAtIndex:path.row] valueForKey:@"image name or image link same as cell for row"]];

    [tableview performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

    [pl release];
}
Run Code Online (Sandbox Code Playgroud)

最后将这些方法放在你的课堂上:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    isDragging_msg = FALSE;     
    [tableview reloadData];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    isDecliring_msg = FALSE;
    [tableview reloadData]; 
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    isDragging_msg = TRUE;
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    isDecliring_msg = TRUE; 
}
Run Code Online (Sandbox Code Playgroud)

  • 大家好.非常感谢您的所有答案.每个人都以自己的方式帮助我解决问题.不过,我主要使用这篇文章的概念.所以只是为了它,我会接受这一个.:) (2认同)