0

I am trying to append new data to Tableview and only reload the Tableview for the new data added.

My app has been crashing giving me this error: "attempt to delete row 19 from section 0 which only contains 10 rows before the update'"

I would like to reload those rows once the asynchronous function contentQueryContinuous() is completed.

Here is my code:

//Once User Scrolls all the way to bottom, beginContentBatchFetch() is called

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentSize.height
    let contentHeight = scrollView.contentSize.height
    if offsetY > contentHeight - scrollView.frame.height {
        beginContentBatchFetch()
    }
}

//Content Batch Fetch looks up to 10 new elements, tries to append to current array's, and then reload's tableview only for those new elements

func beginContentBatchFetch() {
    contentFetchMore = true
    ProgressHUD.show()
    let oldcount = contentObjectIdArray.count
    var IndexPathsToReload = [IndexPath]()
    var startIndex = Int()
    var endIndex = Int()
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  //Calls self.contentQueryContinous which adds new elements
        self.contentQueryContinous()
        let newElements = self.contentObjectIdArray.count - oldcount
        startIndex = oldcount
        endIndex = self.contentObjectIdArray.count
        for index  in startIndex..<endIndex {
            let indexPath = IndexPath(row: index, section: 0)
            IndexPathsToReload.append(indexPath)
            }
        if newElements > 0 {
        self.MyTableView.reloadRows(at: IndexPathsToReload, with: .fade)
        }
        ProgressHUD.dismiss()
      }
  }

Here is contentQueryContinous()

   func contentQueryContinous() {
    if contentObjectIdArray.count != 0 {
        contentSkip = contentObjectIdArray.count
        let query = PFQuery(className: "ContentPost")
        query.whereKey("Spot", equalTo: SpotText)
        query.limit = 10
        query.skip = contentSkip
        query.addDescendingOrder("createdAt")
        query.findObjectsInBackground(block: { (objects: [PFObject]?,error: Error?) in
        if let objects = objects {
            for object in objects {
                    let ProfileImageFile = object["ProfileImage"] as? PFFileObject
                            let urlString = ProfileImageFile?.url as! String
                                        if let url = URL(string: urlString) {
                                            let data = try? Data(contentsOf: url)
                                               if let imageData = data {
                                                   self.contentPostProPicUrlArray.append(urlString as NSString)
                                                   self.contentPostProPicImageCache.setObject(UIImage(data: imageData)!, forKey: urlString as NSString)
                                               }
                                           }
                    if object["Post"] != nil && object["UserLikes"] != nil && object["Username"] != nil && object["UserTime"] != nil {
                        self.contentPostArray.append(object["Post"] as! String)
                        self.contentLikeArray.append(object["UserLikes"] as! Int)
                        self.contentUsernameArray.append(object["Username"] as! String)
                        self.contentTimeArray.append(object["UserTime"] as! String)
                        self.contentObjectIdArray.append(object.objectId!)
              }
            }
            print(self.contentPostArray)
        }
    })
}

}

magellan
  • 63
  • 7

1 Answers1

0

You are trying to reload a cell that is not on the table. Try inserting it. Also, you are risking a race condition.

From the docs

Reloading a row causes the table view to ask its data source for a new cell for that row. The table animates that new cell in as it animates the old row out. Call this method if you want to alert the user that the value of a cell is changing.

Ariel Rodriguez
  • 211
  • 1
  • 4