it-swarm.com.ru

Загрузка дополнительных ячеек внизу 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 не возвращает его обратно.

12
kzia

Я предполагаю, что вы пытаетесь сделать что-то вроде "бесконечной прокрутки" с веб-страниц рабочего стола, где вы загружаете больше контента, когда пользователь попадает в конец страницы. На iOS это не очень часто используемый дизайн. Как правило, разработчики инициализируют свои UITableView или UICollectionView с абсолютным общим количеством записей. Если им нужно передавать данные по сети, они асинхронно загружают данные по мере необходимости (когда ячейки или представления появляются на экране), и до тех пор, пока содержимое не загружается, они отображают какое-то временное содержимое, например, пустое представление со счетчиком.

Тем не менее, если вы хотите выполнять бесконечную прокрутку способом, более похожим на настольное веб-приложение, вы должны реализовать протокол UIScrollViewDelegate (или UICollectionViewDelegate, который является надмножеством) и прослушивать обратный вызов scrollViewDidScroll: . В рамках этого обратного вызова переберите UICollectionView's indexPathsForVisibleItems и проверьте, отображается ли какой-либо из путей индекса на "последний" элемент вашей коллекции, который указывает, что пользователь прокрутил до конца. В этот момент вызовите свою логику, чтобы загрузить больше материала.

0
Idles

В IOS8 есть метод UICollectionViewDelegatewillDisplayCell.

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

В табличном представлении вы должны загрузить больше данных в методе 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];
}
14
Sukhrob

Я знаю, что это старый вопрос, но я предоставлю решение для будущих ищущих ответов. Обычно, когда я делаю бесконечную прокрутку для UITableView, я проверяю, пересекаются ли границы scrollview таблицы с прямоугольником tableFooterView. Представления нижнего колонтитула немного сложнее получить в UICollectionViews, поэтому я создаю прямоугольник в конце collectionView, проверяю, пересекается ли он с границами scrollView, и, если это так, загружаю больше элементов. Я также проверил, что у нас есть по крайней мере что-то в таблице, поэтому я не схожу с ума, пытаясь загрузить больше правильно, когда создается таблица.

Примечание. В этом случае ваш метод more обновит ваш источник данных collectionView, добавив новые элементы. Ваши методы numberOfItems/section должны отражать новые значения.

- (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];
    }
}
4
Ian Hoar

Вы также можете использовать collectionView(_:prefetchItemsAt:) Tutorial 1 и 2 .

0
Nik Kov

Я столкнулся с трудностями при преобразовании ответа @ Сухроба в 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()
0
Akhilendra Singh