UICollection crash Invalid update: invalid number of sections. - ios

The number of sections contained in the collection view after the update (1) must be equal to the number of sections contained in the collection view before the update (1), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted).

Are you basing your numberOfSections off a model of some sort? What's happening is you're inserting a section into your table view somewhere, reloading your table view data, and then the app is crashing because numberOfSections does not equal The number of sections contained in the collection view after the update.
Without seeing your code it's hard to pinpoint where the problem is, but I would do a look for where you're inserting a section and figure out how to update your numberOfSections accordingly.
A basic example would be having a stored variable like
var sectionsCount = 1
and when you insert a section, you can do sectionsCount = sectionsCount + 1 , reload your tableView data, and have :
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sectionsCount.count
}
Remember you always have to update your model that you're basing your table view off of BEFORE you reload the data.

Related

Invalid number of rows in section while trying to reload using reloadsections

I have two sections in the tableview.
Rows in section 0 would change when receiving remote notification (insert) or an expired timer (delete).
Section 1 would always have 8 rows and would change when user refresh, all the 8 items would be changed.
I am trying to reload the entire section 0 after the dateset has changed (use refreshed) using.
self.candidates.remoteAll()
for object in json {
let candidate = Candidate(/* Some data */)
self.candidates.append(candidate!)
}
self.tableView.reloadSections(IndexSet(integer: 1), with: .automatic)
and it somehow throws
Fatal Exception: NSInternalInconsistencyExceptionInvalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).
The number of inconsistent rows are not fixed, sometimes there are 2 before the update and 1 after, sometimes is 0 before and 1 after the update. My guess is that section 0 was inserting or delete rows while user trying to refresh section 1.
But I was trying to refresh section 1, section 0 should do no effect whether or not it has a consistent number of rows. Where am I doing wrong? Thank you.
Update
Here is numberOfRowsInSection
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
if let invitations = self.invitations {
return invitations.count
}
return 0
case 1:
return self.candidates.count
default: return 0
}
}
I am using Realm Result on section 0, and Array on section 1.
I think that in this line of code should be: self.candidates.removeAll()

tableView.deleteRows crashes while trying to delete last row of tableView

So i have a tableViewController which does basic stuff such as listing, deleting and editing. Basically, that tableViewController is listing stuff from a core data, using an auxiliary dictionary to get all the objects and then list them. Everything works fine. I can list all the objects, select them, load them, all fine and with the right values. Except, when i try to delete a middle row and then delete the last row of this tableViewController, it crashes, and I'm mostly certain it crashes on tableView.deleteRows(at: [indexPath], with: .fade).
NOTE: if i delete all the items by order, from the last to the first, it doesn't crash
I've looked for similar solutions but all solutions metion that numberOfRowsInSection should keep an atual value of the rows existing, which I have, using the auxiliary dictionary .count, mentioned before (In code below)
This is the error i get (and once again, i already looked it up, and I always reach the same solution, which I think it's not what is happening in my case):
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (4), 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).'
Some pieces of code:
Definition of my dictionary, called lists:
var lists = [Int : [Product]]()
Then the definition of number of rows:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return lists.count
}
And then, where it crashes:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
lists.removeValue(forKey: indexPath.row) //Deletes the entry on dictionary
deleteProductWithId(row: indexPath.row) //Deletes from the core-data
tableView.deleteRows(at: [indexPath], with: .fade) //Crashes here
//tableView.reloadData()
} 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
}
}
Anyone has any idea what I could be doing wrong?
Thanks in advance
Firstly, don't use dictionary for Tableview as dictionary is unordered while tableview needs ordered data. Second is your dictionary's count is still 4 because lists.removeValue(forKey: indexPath.row) will only set value to nil for that key instead of removing whole keypair. You need to delete whole keypair for this case
User array in this form
var lists = [[Product]]()
and then in cellfor row simply:
lists[indexPath.row]
and for deleting row:
lists.remove(at:indexPath.row)
NOTE: if i delete all the items by order, from the last to the first, it doesn't crash
That's because when you don't delete them in order, the index paths of the cells below the row you just deleted change, but your dictionary keys are not updated to reflect that.
Solution: don't cache index paths (index paths' rows in your case). They are bound to change. Don't mix model identifiers and view identifiers.

NSInternalInconsistencyException occurs when insertng indexPath into tableView but only when row count gets above a certain threshold

I have two tables in which I am dragging and dropping between them: sourceTableView and targetTableView. They each have their own tableViewController. A parentContainerViewController manages a 'slide out' UI which allows the user to 'longPressGesture' on the sourceTableView cell which causes sourceTableView to slide out exposing the targetTableView below at which time the user can 'drop' the dragged cell into place within the targetTableView. All works well as it should until the targetTableView grows to about 21-27 rows in size. Once we get to this size and if I re-run the project I start to get the NSInternalInconsistencyException. The detail of the error reads: reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (27) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
At first I thought I was getting a race condition issue since the number of rows before the update is "0" and after it is "27". Maybe the tableView wasn't able to load before the user drags in the item and calls the insertIndex method on tableView. But then I noticed that it works fine until we get to a certain length. Race condition wouldn't make sense in this case. Now I am thinking it has something to do with with 'visible cell' loaded vs not loaded. But why would it be '0' rows? I have looked all over for the answer. There are many NSInconsistency but none that seem to answer my specific problem.
This is the function call to tell targetTableViewController to insert an item into its datasource then tells targetTableView to insertRowsAtIndexPath :
dragDropDataSource.tableView(self, insertDataItem: item, atIndexPath: indexPath)
self.beginUpdates()
self.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
self.endUpdates()
Here is the targetTableViewController code implementing the above call:
func tableView(tableView: UITableView, insertDataItem dataItem : AnyObject, atIndexPath indexPath: NSIndexPath) -> Void {
if let di = dataItem as? DataItem {
data.insert(di, atIndex: indexPath.row)
}
data is the array that stores the 'DataItems' which are shown in the tableView rows.
Additionally. The targetTableView is initialized with data via a call in its viewDidLoad() to getMyTopTen()
func getMyTopTen() {
let pwAPI = PowWowAPI()
pwAPI.getMyTopTen(self.boardId!) {
(entries:[Entry])in
for(var i=0; i < entries.count; i++) {
let dataItem = DataItem(indexes: String(i), entry: entries[i])
self.data.append(dataItem)
}
}
dispatch_async(dispatch_get_main_queue()) {
self.targetTableView.reloadData()
}
}
I hope I have explained the problem sufficiently. If not please help me make this question better. I am new to asking questions here.

iOS Swift 2 - Error deleting tableView row

I've an error when I try to delete a row from a tableView.
The code goes like the following
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
tableView.reloadData()
}
}
The error printed from Xcode is the following:
Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), 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).
I've read here on Stack this error but I can't figure it out.
:(
Thanks in advance.
You deleted the row from the table, but first you need to delete the corresponding datum from your data model. For example, if your data model is an array, then you might call removeAtIndex on it to remove that row. You must always proceed in this order: adjust the data model, adjust the table view.
(There is no need to reload the data at this time; you can omit that line.)

InsertRowsAtIndexPaths error Swift

I have an uitableview and i try to append it by insertRowsAtIndexPaths function.
The uitableview appends nicely if i simply add data to the data source arrays, but gives me hard time inserting it by the mentioned above function.
Here is my code
func insertData(){
// appending arrays
answersdict.append(answersmain[answertitle1]![0]) // count 1
resultanswers2d.append(carsmain[answertitle1]!) // count 3
self.tableView.reloadData()
// inserting rows
self.tableView.beginUpdates()
let insertedIndexPathRange = 0..<carsmain[answertitle1]!.count + 1 // total count 4
var insertedIndexPaths = insertedIndexPathRange.map { NSIndexPath(forRow: $0, inSection: 1) }
self.tableView.insertRowsAtIndexPaths(insertedIndexPaths, withRowAnimation: .Fade)
self.tableView.endUpdates()
My datasource count for sections is 2 (so section 1 exists) and for numberOfRows - its equal to resultanswers2d[section].count + 1 which gives me 4
So i'm trying to insert 4 rows into the already appended array that has 4 possible rows in that section, but i'm constantly getting errors like
The number of rows contained in an existing section after the update
(4) must be equal to the number of rows contained in that section
before the update (4), plus or minus inserted cells (4 inserted, 0 deleted)
or if i try to hard
malloc_error
Got stuck. Need any insights. Thank you.
Delete the line to reload the table.
insertRowsAtIndexPaths updates the table accordingly.
The number of insertions and the positions in data source and table must match.
Simply don't call self.tableView.reloadData(). The beginUpdate and endUpdate sections should suffice.
UPDATE:
Also, remember to insert the new section too in the beginUpdate endUpdate block.

Resources