Home > Back-end >  Half of the list will be loaded at the beginning, and when it comes to the end of this list, the oth
Half of the list will be loaded at the beginning, and when it comes to the end of this list, the oth

Time:03-24

I have a tableView and json data.I want tableview load half in json data. When table view scroll comes to the end of the first half , the other half will be load.Can anyone know how I can ?

CodePudding user response:

I believe you will have to do some pagination type of processing on your side with the help of scrollViewDidScroll to observe when you reach the end of a the tableview to load the next batch

Start by setting some initial variables to help you track the paging process.

var pageStart = 0
var pageSize = 15

// scrollViewDidScroll will be called several times
// so we need to be able to block the loading process
var isLoadingItems = false

// Array of 50 values which you get from the API
// For example your JSON data
var totalNumberOfItems = (0...49).reduce([Int]())
{ (result, number) in
    
    var array = result
    array.append(number)
    return array
}

// This will periodically be filled with items from totalNumberOfItems
var itemsToLoad: [Int] = []

I create this loading function which helps with adding the items in batches and reloading the tableview appropriately

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)
    loadItems()
}

private func loadItems(withDelay delay: Double = 0) {
    
    // Check that there are items to load
    if pageStart < totalNumberOfItems.count, !isLoadingItems {
        
        isLoadingItems = true
        
        // The delay and dispatch queue is just to show you the
        // loading of data in batches, it is not needed for the
        // solution
        if delay > 0 {
            presentLoader()
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now()   delay) {
            
            if delay > 0 {
                
                // dismiss the loader
                self.dismiss(animated: true, completion: nil)
            }
            
            // Calculate the page end based on the page size or on
            // the number of items remaining to load if the page size
            // is greater than the number of items remaining
            var pageEnd = self.pageStart   self.pageSize - 1
            
            if pageEnd > self.totalNumberOfItems.count {
                let remainingItems = self.totalNumberOfItems.count - self.pageStart - 1
                pageEnd = self.pageStart   remainingItems
            }
            
            let newItems = Array(self.totalNumberOfItems[self.pageStart ... pageEnd])
            self.itemsToLoad.append(contentsOf: newItems)
            self.pageStart = pageEnd   1
            
            let indexPaths = newItems.map { IndexPath(row: $0,
                                                      section: 0) }
            
            // Update the table view
            self.tableView.beginUpdates()
            self.tableView.insertRows(at: indexPaths, with: .fade)
            self.tableView.endUpdates()
            
            // scroll to first newly inserted row
            if let firstNewRow = indexPaths.first {
                self.tableView.scrollToRow(at: firstNewRow,
                                           at: .top,
                                           animated: true)
            }
            
            
            // Unlock the loading process
            self.isLoadingItems = false
        }
    }
}

Then observe if you reached the end using scrollViewDidScroll and reload the tableview to show the inserted rows

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    
    // Check that the current scroll offset is > 0 so you don't get
    // any false positives when the table view is set up
    // and check if the current offset has reached the end
    if scrollView.contentOffset.y >= 0 &&
        scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height) {
        
        print("reached end, load more")
        
        // Load more data
        loadItems(withDelay: 1)
    }
}

Here is how that will look:

UITableView paging reload end of table view scrollview swift iOS

If you found some part difficult to follow or add into your own code, the complete code which can run as is can be found here:

  • Related