2013-06-18 3 views
12

Я пытаюсь автоматически получить и загрузить следующую страницу ячеек, когда пользователь прокручивает нижнюю часть 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 не возвращает его.

+0

'UICollectionView пробелы 'OMG, это был мой случай, я пробовал обычные способы с' willDisplayCell', но просмотр коллекции сбрасывается и становится пустым (wtf). Наконец реализован с помощью 'scrollViewDidScroll'. – SoftDesigner

ответ

0

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

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

+43

«Как правило, разработчики будут инициализировать UITableView или UICollectionView с абсолютным общим количеством записей». [править] –

5

Я знаю, что это старый вопрос, но я предоставлю решение для будущих искателей ответов. Обычно, когда я делаю бесконечную прокрутку в 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]; 
    } 
} 
+0

Это вообще не работает – c0d3Junk13

+0

Что не работает для вас @ c0d3Junk13? –

+1

Работает отлично для меня в моем представлении коллекции – RyanG

13

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

Теперь UICollectionView имеет делегат willDisplayCell в iOS8. – vampirewalk

+0

Что следует реализовать в методе loadMoredata? – BHUMICA

+0

@Bhumica Я обновил свой ответ. Это пример с AFNetworking. – Sukhrob

19

В IOS8 есть UICollectionViewDelegate метод willDisplayCell.

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

, когда я добираюсь до нижней части коллекцииView, он называется в цикле, хотя .. – Mikael

+0

Отсутствие цикла для меня, хорошо работает. – benfwirtz

+0

Я хотел бы добавить к этому некоторые знания о поведении. Если пользователь прокручивается вверх и вниз, хотя в конце этого раздела может возникнуть ситуация, когда loadData() вызывается более одного раза. Я добавил bool для управления, когда loadData() можно снова вызвать. Тем не менее, indexPath.item - это именно динамическая ссылка, которая будет использоваться. Хороший звонок http://stackoverflow.com/users/2604669/nick-wargnier –

0

Я столкнулся с трудностями при преобразовании ответа @ sukhrob в быстрый для моего проекта, поэтому вот его код в 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

Вы также можете использовать Учебник 1 и 2.

Смежные вопросы