Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load More data on Scroll Demand on CollectionView

I am implementing a feature on the collectionView where user scrolls the collectionView at the bottom (20 items) and it requests another set of data (20 more items) from the server.

I have implemented the following two approaches. But I wonder which approach is better? or is there any other better approach which I am not aware of?

The first approach is to use the indexPath in the cellForItemAtIndexPath as follows

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{    
    if(collectionView == productCollectionView)
    {
        __weak ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];

        // load more data
        if(indexPath.row == numberOfItemsPerSection-1)
        {
            numberOfItemsPerSection += 20;
            offset += 20;
            [self loadFromURL];
        }

       // loading image and text happening here.
       // it is not included here 

     return cell;
   }
}

The second approach is to scrollViewDidScroll as follows

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{    
    if (scrollView.contentOffset.y == scrollView.contentSize.height - scrollView.frame.size.height && pElements.count == numberOfItemsPerSection) {
        numberOfItemsPerSection += 20;
        offset += 20;
        [self loadFromURL];
    }
}
like image 250
casillas Avatar asked Jan 28 '17 00:01

casillas


3 Answers

I do this thing through CollectionViewDelegate method like:

 - (void)collectionView:(UICollectionView *)collectionView 
           willDisplayCell:(UICollectionViewCell *)cell 
        forItemAtIndexPath:(NSIndexPath *)indexPath{

     if indexPath.row == numberOfitem.count-1 && !self.waiting  {
           waiting = true;
           self.loadMoreData()
       }
   }


    -(void)loadMoreData(){

       // After getting the response then
        [numberOfitem addObjects : your response in term of array];
        waiting = false;
    }

In swift 4.0

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

// Note: ‘isWating’ is used for checking the paging status Is currency process or not.

   if indexPath.section == self.dataSoruce.list.count - 2 && !isWating { 
      isWating = true
      self.pageNumber += 1
      self.doPaging()
    }
 }

private func doPaging() {
    // call the API in this block and after getting the response 

    self.dataSoruce.append(newData);
    self.tableView.reloadData()
    self.isWating = false // it means paging is done and the user can able request another page request via scrolling the table view at the bottom.

}
like image 188
Yatish Agrawal Avatar answered Nov 16 '22 00:11

Yatish Agrawal


Swift 4.2

When you call reloadData() inside CollectionView delegate method you will see blank cells. You need call it like this.

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    if indexPath.row == collectionView.numberOfItems(inSection: indexPath.section) - 1 {
        updateNextSet()
    }
}

func updateNextSet(){
    print("On Completetion")
    //requests another set of data (20 more items) from the server.
    DispatchQueue.main.async(execute: collectionView.reloadData)
}
like image 23
Elshad Karimov Avatar answered Nov 16 '22 00:11

Elshad Karimov


Swift 3 : CollectionView Delegate method

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        if indexPath.row == numberofitem.count - 1 {  //numberofitem count
            updateNextSet()  
        }
}

func updateNextSet(){
       print("On Completetion")
       //requests another set of data (20 more items) from the server.
}
like image 35
Pranavan SP Avatar answered Nov 16 '22 00:11

Pranavan SP