Reputation: 5577
I am experiencing a crash when I delete a row.
// Updating my data model
....
// apply the updates
self.tableView.beginUpdates()
self.tableView.deleteRows(at: indexPathsToDelete, with: .automatic)
self.tableView.endUpdates()
Steps to reproduce - Add rows - Delete rows, specifically making sure there's some rows outside the current screen (that will then be in screen when the deletion is successful - Repeat until crash occurs
It doesn't always happen so my best guess is that it will happen only when the cells it's trying to load get recycled
This is in 10.0 simulator with Xcode 8.0
*** Assertion failure in -[UITableView _updateWithItems:updateSupport:],
/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.6/UITableView.m:3149
Missing cell for newly visible row 2
(null)
code for cellForRowAt
if isMultipe{
let cell = tableView.dequeueReusableCell(withIdentifier: DetailsTableViewCell.defaultIdentifier, for: indexPath) as! DetailsTableViewCell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: DetailsMultipleTableViewCell.defaultIdentifier, for: indexPath) as! DetailsMultipleTableViewCell
return cell
}
the same bug reported here : https://forums.developer.apple.com/thread/49676
Upvotes: 19
Views: 5138
Reputation: 22763
In my case this happened when I forgot to call super.prepareForReuse()
in my custom subclass.
See https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse:
If you override this method, you must be sure to invoke the superclass implementation.
Upvotes: 0
Reputation: 3447
This problem happened to me when I had cells with different sizes. My code:
tableView.estimatedRowHeight = 150
tableView.rowHeight = UITableViewAutomaticDimension
During moving/inserting/deleting, app was crashing with "Missing cell for newly visible row"
message. So I removed this line:
tableView.estimatedRowHeight = 150
and implement delegate method in which returned separate estimated height for each row.
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {}
Hope it will help someone.
Upvotes: 1
Reputation: 6849
I had a similar problem.
emrekyv suggested to delete estimatedSectionHeaderHeight
but I have a table with one seaction and no header and no footer.
Expanding his idea and setting estimatedRowHeight
to 0 (= not automatic) fixed the problem.
So the rule is:
Do not estimate any height when updating a UITableView.
Upvotes: 0
Reputation: 136
In my case I had this issue just for inserting the first row to an empty section, so I tried to fix it like this:
self.array.append(item)
if self.array.count > 1 {
self.tableView.beginUpdates()
self.tableView.insertRows(at: indexPathes, with: .top)
self.tableView.endUpdates()
} else {
self.tableView.reloadSections([1], with: .fade)
}
Upvotes: 1
Reputation: 71
In my case it was crashing when cells have used autolayout for calculating it's height. So, the only guaranteed solution is use manual calculating heights. (what is actually sad..)
Upvotes: 1
Reputation: 1266
I had the same problem and I found out that UITableView
has serious problems with animating insert/update/delete rows when section headers are variable height. Just convert the height to some constant and try it again.
This actually means deleting estimatedSectionHeaderHeight
.
Upvotes: 8
Reputation: 474
Remove indexPath in tableView.dequeueReusableCell
if isMultipe{
let cell = tableView.dequeueReusableCell(withIdentifier: DetailsTableViewCell.defaultIdentifier) as! DetailsTableViewCell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: DetailsMultipleTableViewCell.defaultIdentifier) as! DetailsMultipleTableViewCell
return cell
}
Upvotes: 0