在UICollectionView的底部加载其他单元格

时间:2013-06-18 23:47:53

标签: ios uicollectionview

当用户滚动到UICollectionView的底部时,我正在尝试自动获取并加载下一页单元格。

我可以在UIButton页脚中添加UICollectoinView来完成此操作。当用户滚动到页脚并触摸按钮时,会正确添加新单元格。可以再次触摸页脚中的UIButton以添加更多页面。

我尝试将其自动化,因此当用户滚动到底部时,会自动调用添加新单元格的正确方法:

- (UICollectionReuseableView *)collectionView: (UICollectionView *)collectionView viewForSupplementaryElementOfKind: (NSString *)kind atIndexPath: (NSIndexPath *) indexPath
{

    // code for headerView
    // ...

    // code for footerView
    MySupplementalFooter *footerView = nil;
    if ( [kind isEqual:UICollectionElementKindSectionFooter] )
    {
        footerView = [self.collectionView dequeueReuseableSupplemntaryViewOfKind:kind withReuseIdentifier:@"FooterId" forIndexPath:indexPath];
        if (LoadMoreIsEnabled) 
        {
            footerView.loadMoreFooterButton.setHidden:NO];
            [self loadMoreFooterButtonAction]; // calls the method to add cells to the dictionary for cv 
        } else 
        {
             footerView.loadMoreFooterButton setHidden:YES];
        }

        return footerView;
    }
}

调用loadMoreFooterButtonAction方法,但整个UICollectionView空白。刷新UICollectionView并不能恢复它。

6 个答案:

答案 0 :(得分:20)

在IOS8中,有UICollectionViewDelegate方法willDisplayCell

func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
    if indexPath.item == (data.count-1) {
        loadData()
    }
}

答案 1 :(得分:15)

在表格视图中,您应该在willDisplayCell()方法中加载更多数据。对于收藏品,没有这样的对应物。但是,你可以这样做。希望,它有所帮助。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    // Other code here ...

    if (indexPath.item == [self.photos count] - 1) {
        [self loadPhotos];
    }

    return cell;
}

- (void)loadPhotos {
    [self showLoadingIndicator];
    self.operation = [client HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        [self hideLoadingIndicator];

        // Get data
        NSArray *photosData = responseObject[@"data"];
        NSInteger numberOfResults = [photosData count];
        NSInteger totalCount = [self.photos count];

        if (numberOfResults > 0) {
            NSMutableArray *indexPaths = [NSMutableArray new];

            for (NSInteger i = 0; i < numberOfResults; i++) {
                Photo *photo = [Photo new];
                photo._id = [photoData[@"id"] integerValue];
                photo.url = photoData[@"url"];

                [self.photos addObject:photo];
                [indexPaths addObject:[NSIndexPath indexPathForRow:totalCount + i
                                                     inSection:0]];
            }

            [self.collectionView performBatchUpdates:^{
                [self.collectionView insertItemsAtIndexPaths:indexPaths];
            } completion:nil];
        }        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [self hideLoadingIndicator];
        // Handle error here
    }];

   [self.operation start];
}

答案 2 :(得分:4)

我知道这是一个老问题,但我会为未来的求职者提供解决方案。通常当我在UITableView上进行无限滚动时,我将检查tableView的scrollview的边界是否与tableFooterView的rect相交。在UICollectionViews中获取页脚视图有点复杂,所以我在collectionView的末尾创建一个rect,看它是否与scrollView边界相交,如果是,我加载更多的项目。我还检查过表中至少有一些内容,所以当表实例化时,我不会试图加载更多权限。

注意:在这种情况下,您的more方法将更新您的collectionView数据源,并附加新项目。您的numberOfItems / sections方法应该反映新的计数。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (CGRectIntersectsRect(scrollView.bounds, CGRectMake(0, self.collectionView.contentSize.height, CGRectGetWidth(self.view.frame), 40)) && self.collectionView.contentSize.height > 0)
    {
        [self more];
    }
}

答案 3 :(得分:0)

我假设您正在尝试从桌面网页执行类似“无限滚动”的操作,您可以在用户到达页面底部时加载更多内容。在iOS上,这不是一个非常常用的设计。通常,开发人员将使用绝对总条目数初始化其UITableView或UICollectionView。如果他们需要通过网络传输数据,他们会根据需要异步加载数据(当单元格或视图出现在屏幕上时),直到内容加载它们显示某种临时内容,如带有微调器的空白视图。

也就是说,如果你想以更像桌面Web应用程序的方式进行无限滚动,你应该实现UIScrollViewDelegate协议(或UICollectionViewDelegate,它是一个超集)并监听scrollViewDidScroll:回调。在该回调中,遍历UICollectionView的indexPathsForVisibleItems并检查是否有任何索引路径映射到集合中的“last”项,这表示用户已滚动到最后。那时,调用你的逻辑加载更多东西。

答案 4 :(得分:0)

我很难将@ sukhrob的回答转换为我的项目的swift,所以这是他在Swift 3中的代码,便于复制和粘贴。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // Other code here ...
        if indexPath.item == photos.count() - 1 {
            loadPhotos()
        }
        return cell
    }

    func loadPhotos() {
        showLoadingIndicator()
        operation = client.httpRequestOperation(with: request, success: {(_ operation: AFHTTPRequestOperation, _ responseObject: Any) -> Void in
            self.hideLoadingIndicator()
                // Get data
            let photosData: [Any] = responseObject["data"]
            let numberOfResults: Int = photosData.count
            let totalCount: Int = photos.count()
            if numberOfResults > 0 {
                var indexPaths = [Any]()
                var i = 0
                while i < numberOfResults {
                    let photo = Photo()
                    photo.id = CInt(photoData["id"])
                    photo.url = photoData["url"]
                    photos.append(photo)
                    indexPaths.append(IndexPath(row: totalCount + i, section: 0))
                    i
                }
                i += 1

        collectionView?.performBatchUpdates({() -> Void in
                    collectionView?.insertItems(at: indexPaths as? [IndexPath] ?? [IndexPath]())
                }) { _ in }
            }
        }, failure: {(_ operation: AFHTTPRequestOperation, _ error: Error?) -> Void in
            self.hideLoadingIndicator()
            // Handle error here
        })
        operation.start()

答案 5 :(得分:0)

您还可以使用collectionView(_:prefetchItemsAt:) 教程12