2013-06-18 3 views
12

사용자가 UICollectionView의 맨 아래로 스크롤 할 때 셀의 다음 페이지를 자동으로로드하려고합니다.UICollectionView 아래에 추가 셀로드

UICollectoinView 하단에 UIButton을 추가하여 입력 할 수 있습니다. 사용자가 꼬리말로 스크롤하여 버튼을 터치하면 새 셀이 올바르게 추가됩니다. 더 많은 페이지를 추가하기 위해 바닥 글에 UIButton을 다시 터치 할 수 있습니다. 전체 UICollectionView 블랭크 아웃

- (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 메소드 호출되지만 :

는 I 하단에 사용자가 스크롤을 새로운 셀을 추가하기위한 적절한 방법은 자동으로 호출 될 때 때문에 자동화했습니다. UICollectionView을 새로 고치면 다시 가져 오지 않습니다.

+0

'UICollectionView가 OMG을 공백으로 만들었습니다. 제 경우는'willDisplayCell'으로 일반적인 방법을 시도했지만 콜렉션 뷰는 재설정되고 공백 (wtf)이됩니다. 마지막으로'scrollViewDidScroll'을 사용하여 구현됩니다. – SoftDesigner

답변

0

사용자가 페이지 하단에있을 때 더 많은 콘텐츠를로드하는 데스크톱 웹 페이지에서 '무한 스크롤'과 같은 작업을하려는 것으로 가정합니다. iOS에서는 매우 일반적으로 사용되는 디자인이 아닙니다. 일반적으로 개발자는 절대 총 항목 수를 사용하여 UITableView 또는 UICollectionView를 초기화합니다. 네트워크를 통해 데이터를 스트리밍해야하는 경우 필요에 따라 비동기 적으로 데이터를로드하고 (셀 또는 뷰가 화면에 표시 될 때) 컨텐츠가로드 될 때까지 스피너가있는 빈보기와 같은 일종의 임시 컨텐츠를 표시합니다.

말하자면 데스크톱 웹 앱과 같은 방식으로 무한 스크롤을 수행하려면 UIScrollViewDelegate 프로토콜 (또는 상위 집합 인 UICollectionViewDelegate)을 구현하고 scrollViewDidScroll: 콜백을 수신해야합니다. 해당 콜백 내에서 UICollectionView의 indexPathsForVisibleItems을 반복하고 인덱스 경로가 컬렉션의 '마지막'항목에 매핑되는지 확인하여 사용자가 끝까지 스크롤했음을 나타냅니다. 이 시점에서 로직을 호출하여 더 많은 내용을로드하십시오.

+43

"일반적으로 개발자는 절대 총 항목 수를 사용하여 UITableView 또는 UICollectionView를 초기화합니다." [표창장 필요] –

5

나는 이것이 오래된 질문 인 것을 알고 있지만 앞으로 답변을 구하는 사람들에게 해결책을 제시 할 것입니다. 일반적으로 UITableView에서 무한 스크롤을 할 때 tableview의 스크롤 뷰의 경계가 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]; 
    } 
} 
+0

전혀 작동하지 않습니다 – c0d3Junk13

+0

@ c0d3Junk13에서 효과가없는 것은 무엇입니까? –

+1

내 컬렉션보기에서 나를 위해 위대한 작품 – RyanG

13

willDisplayCell() 메소드에서 더 많은 데이터를로드해야합니다. 컬렉션에는 이와 같은 대응 물이 없습니다. 그러나, 당신은 이렇게 할 수 있습니다. 희망, 도움이됩니다. iOS8의에서는

- (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는 iOS8에서 willDisplayCell 대리자를 갖습니다. – vampirewalk

+0

loadMoredata 메서드에서 무엇을 구현해야합니까? – BHUMICA

+0

@Bhumica 제 답변을 업데이트했습니다. 이것은 AFNetworking의 예입니다. – Sukhrob

19

UICollectionViewDelegate 방법 willDisplayCell있다.

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

내가 collectionView의 맨 아래에 도달했을 때 루프에서 호출되었습니다. – Mikael

+0

나를위한 루프가 없습니다. 잘 작동합니다. – benfwirtz

+0

이것에 약간의 행동 지식을 추가하고 싶습니다. 사용자가 위와 아래로 스크롤하는 경우이 섹션의 끝에서 loadData()가 두 번 이상 호출되는 상황이 발생할 수 있습니다. loadData()가 다시 호출 될 수있을 때 제어 할 bool을 추가했습니다. 그러나 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

또한 튜토리얼 12를 사용할 수 있습니다.