dang
dang

Reputation: 2412

Pagination for UICollectionView

I have created datatable view using UICollectionView.

This is the code:

class PanelViewController: UIViewController{

var TableHeaderArray = NSMutableArray()
var TableDataArray = NSMutableArray()
var NumberOfRows = Int()   
var UlockDataArray = NSMutableArray()
let dataSource = DataSource()

override func viewDidLoad() {
    super.viewDidLoad()

    dataSource.populateData()

    let noOfRows = dataSource.NumberOfRows
    self.NumberOfRows = noOfRows + 1

    self.UlockDataArray = dataSource.DUDataArray
    self.TableDataArray = dataSource.DTableDataArray   


    let layout: CustomCollectionViewLayout = CustomCollectionViewLayout()

    DataTableCollectionView = UICollectionView(frame: CGRect(x:0, y:0, width:self.TableVu.bounds.width, height:self.TableVu.bounds.height), collectionViewLayout: layout)
    DataTableCollectionView.dataSource = self
    DataTableCollectionView.delegate = self
    self.DataTableCollectionView .registerNib(UINib(nibName: "FixedCellIdentifier", bundle: nil), 
        forCellWithReuseIdentifier: FixedCellIdentifier)
    self.DataTableCollectionView .registerNib(UINib(nibName: "DynamoCellIdentifier", bundle: nil),
     forCellWithReuseIdentifier: DynamoCellIdentifier)

    self.TableVu.addSubview(DataTableCollectionView)        
    self.view.addSubview(TableVu)

}

}

extension PanelViewController : UICollectionViewDataSource, UICollectionViewDelegate{
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int{        
        return self.NumberOfRows
    }

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {     
    return dataSource.TableHeaders.count        
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    // My Code to Create Cells using data from TableHeaderArray, TableDataArray and UlockDataArray

}


func scrollViewDidScroll(scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
   let contentHeight = scrollView.contentSize.height
   var returnUmidData = NSMutableArray()
   var returnTableData = NSMutableArray()

   if offsetY > contentHeight - scrollView.frame.size.height {   

        self.dataSource.populateData()

        returnUData = self.dataSource.DUDataArray
        returnTableData = self.dataSource.DTableDataArray


        let seconds = 5.0
        let delay = seconds * Double(NSEC_PER_SEC)
        let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

        dispatch_after(dispatchTime, dispatch_get_main_queue(), {

             self.NumberOfRows += returnTableData.count

             let mergetWorkoutData = NSMutableArray(array: self.UlockDataArray)
             mergetWorkoutData.addObjectsFromArray(returnUmidData as [AnyObject])

             self.UlockDataArray = mergetWorkoutData

             let mergetWorkoutTabelData = NSMutableArray(array: self.TableDataArray)
             mergetWorkoutTabelData.addObjectsFromArray(returnTableData as [AnyObject])

             self.TableDataArray = mergetWorkoutTabelData 

            self.DataTableCollectionView!.reloadData()

        })
   }
}

}

Initialy, I am displaying first 50 records. I need to implement pagination on vertical scroll. Each time user reach to end of scroll, I want to make an API call to get the next 50 records.

But in doing so, I am getting an error

"Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]:
 index 51 beyond bounds [0 .. 50]'"

I think somehow indexPath is not getting updated but unable to understand where and why or how to update it. Can you please advise?

Upvotes: 2

Views: 9689

Answers (4)

Mitul Pokiya
Mitul Pokiya

Reputation: 172

for easy way to use Pagination you need to use willDisplay cell mathod

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        if currentPage < totalPage && indexPath.item == array.count - 1 {
            currentPage += 1
            // pass currenPage number in API
            // add data to array
            // reload collectionview
        }
    }

Upvotes: 0

Adnan T.
Adnan T.

Reputation: 1176

You can try below code:

func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath)
        {
            if NumberOfRows >= indexPath.row
            {
                // call API
                // add data to array
                // reload collectionview
                NumberOfRows == TableDataArray.count
            }
        }

Upvotes: 1

Annie Gupta
Annie Gupta

Reputation: 2822

I think instead of

func scrollViewDidScroll(scrollView: UIScrollView)

you can use the below UICollectionViewDelegate method:-

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)`

Upvotes: 1

Lazy
Lazy

Reputation: 680

Why don't you use collectionView's willDisplayCell method, which is more manageable.

func collectionView(_ collectionView: UICollectionView, 
             willDisplay cell: UICollectionViewCell, 
               forItemAt indexPath: IndexPath) {
    if indexPath.row + 1 == dataSource.count && dataSource.count < myPaginationUpperLimit {
        paginateMore()
    }
}

Upvotes: 4

Related Questions