So I've my app crashing everytime I try to delete the last cell of the section.
Ex., if my section has 10 rows, I can delete them without any problem but the last one throws the following error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (3), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'
I've searched around here and found some ways to fix this problem, but I tried them all and couldn't get this issue fixed, it still crashes and throws the same error.
The related parts of my code goes as it follows:
override func numberOfSections(in tableView: UITableView) -> Int {
if (main_arr.count > 0 && sub_arr.count > 0) {
self.numberOfSections = 3
} else {
self.numberOfSections = 2
}
return self.numberOfSections
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (section == 0) {
return 1
} else if (section == 1 && main_arr.count > 0) {
return main_arr.count
} else {
return sub_arr.count
}
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
switch indexPath.section {
case 1:
main_arr.remove(at: indexPath.row)
case 2:
sub_arr.remove(at: indexPath.row)
default:
print("default 001")
}
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
EDIT 1
I tried to handle the global variable, responsible for the numberOfSections so when any of my arrays.count == 0 it will be decreased by 1, but it didn't solved the issue.
I do understand completely the error message, like, if I've 3 sections, and I delete the whole content of one of them, I should delete one section and delete it from the datasource as well.
The problem is that
numberOfSections
returns different values before and after you delete rows, but you don't delete any sections. So you should either return a constant value in numberOfSections or calldeleteSections
in addition todeleteRows
The main thing to remember is the following:
UITableView must always contain the same number of rows and sections as your dataSource.
You cannot just return a new value in
numberOfSections
ornumberOfRows
dataSource methods. Every change should be compensated with delete/insert rows(sections) method. And vice versa: if you delete/insert to tableView, you must return corresponding values in dataSource methods. Just as your exception message states:It's because 3+0≠1. In this case you should have deleted two sections to avoid crash.
The error message is actually very helpful. It talks about sections - it expected not to change, but it found a different value after your operation.
Basically, UIKit did check the number of sections and rows before calling your code, runs your code, and then checks if the the new numbers line up with your operations. In you case, it doesn't - because you are calling
deleteRows
(which should decrease the row count for the given section), but yournumberOfSections
delegate gives a different result now. So you either want to calldeleteSections
or keep the sectionCount unmodified.BTW, it is not forbidden to return
0
as the number of rows for a section - maybe this is just what you want here.A further note: I don't think that storing the number of sections in an instance variable is a good thing here. It makes for double bookkeeping.