Подтвердить что ты не робот

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

4b9b3361

Ответ 1

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

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

Ответ 2

В IOS8 существует метод UICollectionViewDelegate willDisplayCell.

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

Ответ 3

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

Ответ 4

Я знаю, что это старый вопрос, но я предоставлю решение для будущих ищущих ответ. Обычно, когда я делаю бесконечную прокрутку на UITableView, я проверю, пересекаются ли границы прокрутки viewView TableView с прямоугольником tableFooterView. Представления нижнего колонтитула немного сложнее получить в UICollectionViews, поэтому я создаю прямоугольник в конце коллекцииView, чтобы увидеть, пересекается ли он с границами 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];
    }
}

Ответ 5

Мне не удалось преобразовать ответ @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()

Ответ 6

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