Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView load more data when scrolling to top?

How could I load more data while scrolling to the top without losing the current offset oh the UITableView?

Here is what I am trying to achieve:

This is the whole set of data:

row 1
row 2
row 3
row 4
row 5
row 6
row 7
row 8*
row 9
row 10
row 11
row 12
row 13
row 14
row 15

Now, imagine that the user loaded the ones marked in bold and the offset is at row 8, if the user scroll up and reached row 7, I want to load and insert the rows from 1 to 5 without jumping from row 7. Keeping in mind that the user may be scrolling so when data reached the phone it is at row 6, so I can't jump it back to row 7, but keep the scroll smooth and natural (just how happen when you load more data while scrolling down, that the data is reloaded without the tableview jumping from between rows).

By the way, by offset I mean the contentOffset property of the UITableView.

Thanks for your help, I do really appreciate it!

like image 946
Abraham Duran Avatar asked Mar 22 '26 15:03

Abraham Duran


2 Answers

When you are updating your data, you need to get the current offset of the tableView first. Then, you can add the height of the added data to the offset and set the tableView's offset like so:

func updateWithContentOffsset(data: [String]) {
    guard let tableView = tableView else {
        return
    }
    let currentOffset = tableView.contentOffset
    let yOffset = CGFloat(data.count) * tableView.rowHeight // MAKE SURE YOU SET THE ROW HEIGHT OTHERWISE IT WILL BE ZERO!!!
    let newOffset = CGPoint(x: currentOffset.x, y: currentOffset.y + yOffset)
    tableView.reloadData()
    tableView.setContentOffset(newOffset, animated: false)
}

You can also take a look at the gist that I created. Simply open up a new iOS Playground and copy-paste the gist.

The only thing you have to be aware of is that make sure you know your row height to add to the offset.

like image 76
Pratik Patel Avatar answered Mar 25 '26 05:03

Pratik Patel


@Pratik Patel Bellow answer is best one. Right down or call bellow function in the web-service response.

func updateWithScroll(data: [String]) {
    guard let tableView = tableView else {
        return
    }
    guard let currentVisibleIndexPaths = tableView.indexPathsForVisibleRows else {
        return
    }
    var updatedVisibleIndexPaths = [IndexPath]()
    for indexPath in currentVisibleIndexPaths {
        let newIndexPath = IndexPath(row: indexPath.row + data.count, section: indexPath.section)
        updatedVisibleIndexPaths.append(newIndexPath)
    }
    tableView.reloadData()
    tableView.scrollToRow(at: updatedVisibleIndexPaths[0], at: .top, animated: false)
}
like image 26
Chetan kasundra Avatar answered Mar 25 '26 05:03

Chetan kasundra