Uitableview Pagination - Bottom Refresh to Load New Data in Swift

UITableView Pagination - Bottom Refresh to Load New Data in Swift

Nope, you can't go with that approach because cellForRowAtIndexPath is called many times and also it will take much time to check your conditions!

Here, I have found a better option for UITableView pagination.

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {

//Bottom Refresh

if scrollView == tableView{

if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height)
{
if !isNewDataLoading{

if helperInstance.isConnectedToNetwork(){

isNewDataLoading = true
getNewData()
}
}
}
}
}

isNewDataLoading is Bool to check that UITableView is loading new data or not!

Hope this helps!

UITableView load more when scrolling to bottom like Facebook application

You can do that by adding a check on where you're at in the cellForRowAtIndexPath: method. This method is easy to understand and to implement :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Classic start method
static NSString *cellIdentifier = @"MyCell";
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MainMenuCellIdentifier];
}

MyData *data = [self.dataArray objectAtIndex:indexPath.row];
// Do your cell customisation
// cell.titleLabel.text = data.title;

BOOL lastItemReached = [data isEqual:[[self.dataArray] lastObject]];
if (!lastItemReached && indexPath.row == [self.dataArray count] - 1)
{
[self launchReload];
}
}

EDIT : added a check on last item to prevent recursion calls. You'll have to implement the method defining whether the last item has been reached or not.

EDIT2 : explained lastItemReached

Swift tableView Pagination

For that you need to have server side change also.

  1. Server will accept fromIndex and batchSize in the API url as query param.

    let listUrlString =  "http://bla.com/json2.php?listType=" + listType + "&t=" + NSUUID().UUIDString + "&batchSize=" + batchSize + "&fromIndex=" + fromIndex
  2. In the server response, there will be an extra key totalItems. This will be used to identify all items are received or not. An array or items fromIndex to batchSize number of items.

In the app side

  1. First loadItem() will be called with fromIndex = 0 and batchSize = 20 (for example in viewDidLoad() or viewWillAppear). removeAll items from privateList array before calling loadItem() for the first time

  2. Server returns an array of first 20 items and totalItems total number of items in the server.

  3. Append the 20 items in privateList array and reload tableView

  4. In tableView:cellForRowAtIndexPath method check if the cell is the last cell. And check if totalItems (form server) is greater than privateList.count. That means there are more items in the server to load

    if indexPath.row == privateList.count - 1 { // last cell
    if totalItems > privateList.count { // more items to fetch
    loadItem() // increment `fromIndex` by 20 before server call
    }
    }

Question: where is refresh ? will be scrolling ?

Refresh after appending new items in the array when server response received. (step 3)

Scrolling will trigger tableView:cellForRowAtIndexPath for every cell when user scrolls. Code is checking if it is the last cell and fetch remaining items. (step 4)

Sample project added:
https://github.com/rishi420/TableViewPaging

Weird behaviour of UITableViewCell after table reload when paging enabled for UITableView

Link it to tableView's height, your table view has all sizes you need.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) {
// ...
cell.viewHeight.constant = tableView.frame.size.heigh
// ...
}

or remove viewHeight constraint and use delegate method to set row height

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.size.height
}

UPD:

TableView using estimatedRowHeight to calculate its scroll offsets. This does create an issue during reload if we have enabled paging and do not configure estimatedRowHeight.

Solution 1:
Implement estimatedHeightForRowAt delegate

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.size.height
}

Solution 2:
Set tableView.estimatedRowHeight = 0 and use heightForRowAt delegate instead of viewHeight constraint



Related Topics



Leave a reply



Submit