Ios 加载时停止并准备collectionview

Ios 加载时停止并准备collectionview,ios,objective-c,uicollectionview,Ios,Objective C,Uicollectionview,我有一个collectionView(productCollectionView),它根据类别(电子、汽车、商品等)从服务中获取数据 假设用户决定提取电子类别中的数据,在加载数据时,用户更改了类别并获取新的数据集 我已经实现了以下逻辑,但是有点慢。有更好的方法吗 -(void) refreshProducts { if([self.pElements count]){ [self.pElements removeAllObjects]; [self.pro

我有一个
collectionView
(productCollectionView),它根据类别(电子、汽车、商品等)从服务中获取数据

假设用户决定提取电子类别中的数据,在加载数据时,用户更改了类别并获取新的数据集

我已经实现了以下逻辑,但是有点慢。有更好的方法吗

-(void) refreshProducts
{
    if([self.pElements count]){
        [self.pElements removeAllObjects];
        [self.productCollectionView reloadData];
    }
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^(void) {
        [self loadFromURL]; // fetch new data
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    });
}

-(void)loadFromURL {   

    NSMutableDictionary * params = [[NSMutableDictionary alloc]init];
    NSString * category = [[NSUserDefaults standardUserDefaults]objectForKey:@"category"];
    if (category != NULL && ![category isEqualToString: @""]) {
        params[@"category"] = category;
    }

   // offset increments based on scrolling down, +20
    params[@"offset"] = [NSString stringWithFormat:@"%d",offset];

    [self.manager POST:PRODUCT_URL parameters:params success:^(AFHTTPRequestOperation * _Nonnull operation, id responseObject) {
            // getting only 20 data every time, and append to the existing array
            [self.pElements addObjectsFromArray:responseObject];
            [self.productCollectionView reloadData];
    } failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {
    }];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
   __weak ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];        
    cell.productImage.image = [cell.productImage.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    NSString *URL =[NSString stringWithFormat:@"http://www.xxxx.com/xxxx/images/%@", [[[[pElements objectAtIndex:indexPath.row]objectForKey:@"pdetail"] objectForKey:@"images"]objectForKey:@"pimagePath"]];
    cell.productImage.layer.cornerRadius = 10;        
    NSURL *url = [NSURL URLWithString:URL];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [cell.productImage setImageWithURLRequest:request
                          placeholderImage:nil
                                   success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {

                                       cell.productImage.image = image;
                                       [cell setNeedsLayout];

                                   } failure:nil];

    return cell;
 }

您发布的代码太模糊,我们无法提供太多帮助

看起来您的
loadFromURL
方法加载了您的所有产品,然后告诉集合视图在完成后重新加载

如果为真,则会产生延迟,因为在加载完成之前不会发生任何事情。最好在
collectionView(\uu:cellForItemAt:)
中一次请求一个项目,将其内容保存到磁盘上的一个文件中,然后将该内容安装到该索引路径的单元格中,假设它仍在屏幕上。如果一个单元格在加载之前就从屏幕上滚下来了,那么您仍然可以从磁盘上的文件中加载它的数据,而不是重新下载它


这种方法将只加载可见的单元格,每个单元格都将在其内容加载完成时显示,从而使屏幕开始更新的速度更快。

不包括加快服务器速度或缩小查询范围,获得计算节省的唯一其他方法是在用户更改类别时取消当前的飞行中请求

为此,请将任务保留在属性中

@property(strong,nonatomic) NSURLSessionDataTask *productTask;
然后在开始新帖子之前取消最后一篇帖子(如果存在的话)

[self.productTask cancel];
self.productTask = [self.manager POST:PRODUCT_URL parameters:params success:^(AFHTTPRequestOperation * _Nonnull operation, id responseObject) {
    // etc.

除此之外,还有一些UI技巧可以让用户更快地感知时间。(@duncac有一个好主意,只加载可见的行,并在获取它们时重新加载,但不清楚能否以较小的批量获取它们)。其他一些类似的想法是进度条、活动指示器或。

实际上
loadFromURL
有一个参数是
offset
,每次调用此方法时,它一次只带来20个项目,而不是所有项目。我没有获得所有图像,在
loadURL
中,我保留了图像URL,然后使用它
cellForItemAtIndexPath
我还更新了我的问题。。只是添加了更多代码以使其更清晰。但是您在获取记录后调用reloadData,这会强制整个集合视图重新加载。对不起,我的初始问题我特意将其放在那里以传达我的问题。但是,当我更新了问题并放入整个代码时,它不在实际代码中,因为它已经在
loadFromURL