rocky raccoon rocky raccoon -4 years ago 88
iOS Question

Deleting cell leads to a crash

So my

numberOfRowsInSection
is:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let delegate = delegate else { return 0 }
return delegate?.comments.count + 1
}


I added one more to compensate for the "load more" which is on top of the table view (in this case, it's row 0).

Here's the thing: when I want to remove that cell "load more" after fetching the max amount of posts, it gives me an error:

The number of rows contained in an existing section after the update (12) must be equal to the number of rows contained in that section before the update (11), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'


So here's the function that causes the error:

func loadMore() {
// loadMoreComments(completion:) inserts the new comment objects inside
// the data source in the beginning of the list.
delegate?.loadMoreComments(completion: { (isEndOfPosts, newCommentCount, comments) in
self.didReachEndOfPosts = isEndOfPosts
if isEndOfPosts {
// indexPaths just returns [[0,1]], or, just one row.
let indexPaths = self.createIndexPathsForNoMorePosts(newCommentCount: newCommentCount)
self.tableView.beginUpdates()
// error happens here.
self.tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
self.tableView.endUpdates()

// assume only one post comes in, and that's the last one.
self.tableView.beginUpdates()
self.tableView.insertRows(at: indexPaths, with: .automatic)
self.tableView.endUpdates()
}
}


What I'm trying to accomplish is this: once i get the last post, remove the "load more" cell, and insert the last few posts, replacing the 0 row with the first of the last few posts.

Answer Source

You need to notify your tableView's datasource about cell count change. Create a class variable, something like

var shouldShowLoadMoreCell = true

and than modify numberOfRowsInSection method

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   guard let delegate = delegate else { return 0 }
   if shouldShowLoadMoreCell {
       return delegate?.comments.count + 1
   } else {
       return delegate?.comments.count
   }
}

finally, set this flag when needed

self.tableView.beginUpdates()
shouldShowLoadMoreCell = false
self.tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
self.tableView.endUpdates()
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download