简体   繁体   中英

ios insert more table cell rows after last index

I'm trying to make an unlimited scroll table view(feed). However, I can't get the tableview to insert more cells after the initial load.

My table has two types of cells. A collection view table cell and a regular image+label table cell. The collection view is shown only once and it's first.

Area that is giving me issues. It does at least call, it just doesn't add any more cells. Also, not sure how it knows which type of cell to add.

extension FeedViewController: UITableViewDelegate{
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let lastElement = venueData.count
        if indexPath.row == lastElement {
            // handle your logic here to get more items, add it to dataSource and reload tableview
            print(venueData.count)
            print("last")
            if(firstLoad){
                firstLoad = false
                return
            }
            let appendAmount = 10
            currentOffset = currentOffset+appendAmount

            let res = venueDataRequest(query:"Any",offset:10,amount:appendAmount)
            venueData.append(contentsOf: res )


            self.feedTableView.beginUpdates()
            self.feedTableView.insertRows(at: [IndexPath(row: venueData.count-appendAmount, section: 0)], with: .automatic)
            self.feedTableView.endUpdates()


        }
    }
}

Full Class

import UIKit

class FeedViewController: UIViewController {

    @IBOutlet weak var feedTableView: UITableView!


    let popularPlaces = getPopularPlaces()
    var firstLoad = true
    var currentOffset = 0
    var venueData = venueDataRequest(query:"Any",offset:0,amount:10)
//    var venueData: [FeedVenueData] = []


    override func viewDidLoad() {
        super.viewDidLoad()
        feedTableView.dataSource = self
        feedTableView.delegate = self
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

extension FeedViewController: UITableViewDelegate{
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let lastElement = venueData.count
        if indexPath.row == lastElement {
            // handle your logic here to get more items, add it to dataSource and reload tableview
            print(venueData.count)
            print("last")
            if(firstLoad){
                firstLoad = false
                return
            }
            let appendAmount = 10
            currentOffset = currentOffset+appendAmount

            let res = venueDataRequest(query:"Any",offset:10,amount:appendAmount)
            venueData.append(contentsOf: res )


            self.feedTableView.beginUpdates()
            self.feedTableView.insertRows(at: [IndexPath(row: venueData.count-appendAmount, section: 0)], with: .automatic)
            self.feedTableView.endUpdates()


        }
    }
}

extension FeedViewController: UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1+venueData.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if(indexPath.row == 0){
            let cell = tableView.dequeueReusableCell(withIdentifier: "FeedPopularPlaceCollectionViewTableViewCell", for: indexPath) as! FeedPopularPlaceCollectionViewTableViewCell
            cell.setup()
            return cell
        }else{
            let cell = tableView.dequeueReusableCell(withIdentifier: "FeedVenueTableViewCell", for: indexPath) as! FeedVenueTableViewCell

            let pos = indexPath.row - 1
            cell.venueName.text = venueData[pos].name
            cell.venueImage.image = venueData[pos].image

            print(indexPath.row)
            return cell
        }
    }

}

You can use this code to insert more rows, when user comes to last cell.

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    //Bottom Refresh
    if scrollView == feedTableView {
        if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height) {
            //Insert Row in Tableview
        print(venueData.count)
        print("last")
        if(firstLoad){
            firstLoad = false
            return
        }
        let appendAmount = 10
        currentOffset = currentOffset+appendAmount

        let res = venueDataRequest(query:"Any",offset:10,amount:appendAmount)
        venueData.append(contentsOf: res )


        self.feedTableView.beginUpdates()
        self.feedTableView.insertRows(at: [IndexPath(row: venueData.count-appendAmount, section: 0)], with: .automatic)
        self.feedTableView.endUpdates()

        }
    }
}

The problem is because you add 10 items but only insert 1 cell. After first time called, if indexPath.row == lastElement will never reached again because indexPath.row = 1 and lastElement = 10 .

To fix it, instead of inserting only 1 cell, insert 10 cells after adding new items and call insertRows on main queue

var indexPaths = (venueData.count-appendAmount+1..<venueData.count+1).map { IndexPath(row: $0, section: 0) }
DispatchQueue.main.async {
    self.feedTableView.insertRows(at: indexPaths, with: .automatic)
}

At this line

 self.feedTableView.insertRows(at: [IndexPath(row: venueData.count-appendAmount, section: 0)], with: .automatic)

why you insert at index venueData.count-appendAmount

self.feedTableView.insertRows(at: [IndexPath(row: venueData.count, section: 0)], with: .automatic)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM