Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) 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 (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).
I'm trying to add rows to a table view when a user taps a row, to create an expandable section, however the extra rows aren't being counted before Xcode tries to add them in and as such causes this error (I think). Can anybody point me in the right direction?
// sectionExpanded is set to false in viewDidLoad. It is set to true when
// the user taps on the expandable section (section 0 in this case)
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 && sectionExpanded {
return 5
} else {
return 1
}
}
// This should recount the rows, add the new ones to a temporary array and then add
// them to the table causing the section to 'expand'.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedItem = menu[indexPath.row]
let cell = tableView.cellForRowAtIndexPath(indexPath) as MenuCell
if indexPath.section == 0 {
var rows: Int
var tmpArray: NSMutableArray = NSMutableArray()
sectionExpanded = !sectionExpanded
rows = tableView.numberOfRowsInSection(0)
for i in 1...rows {
var tmpIndexPath: NSIndexPath
tmpIndexPath = NSIndexPath(forRow: i, inSection: 0)
tmpArray.addObject(tmpIndexPath)
}
if !sectionExpanded {
tableView.deleteRowsAtIndexPaths(tmpArray, withRowAnimation: UITableViewRowAnimation.Top)
} else {
tableView.insertRowsAtIndexPaths(tmpArray, withRowAnimation: UITableViewRowAnimation.Top)
}
} else {
delegate?.rightItemSelected(selectedItem)
}
}
It is telling you that you are trying to insert 1 new row, but numberofrows should be 5, before was 1 and you are trying to insert 1 new row, thats 2. Theres your problem.
rows = tableView.numberOfRowsInSection(0) //this returns 1
for i in 1...rows { //
var tmpIndexPath: NSIndexPath
tmpIndexPath = NSIndexPath(forRow: i, inSection: 0)
tmpArray.addObject(tmpIndexPath)//this will contain only 1 object, because the loop will run only for 1 cycle
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedItem = menu[indexPath.row]
let cell = tableView.cellForRowAtIndexPath(indexPath) as MenuCell
if indexPath.section == 0 {
var rows: Int
var tmpArray: NSMutableArray = NSMutableArray()
sectionExpanded = !sectionExpanded
rows = 1
if sectionExpanded {
rows = 5
}
for i in 1...rows {
var tmpIndexPath: NSIndexPath
tmpIndexPath = NSIndexPath(forRow: i, inSection: 0)
tmpArray.addObject(tmpIndexPath)
}
if !sectionExpanded {
tableView.deleteRowsAtIndexPaths(tmpArray, withRowAnimation: UITableViewRowAnimation.Top)
} else {
tableView.insertRowsAtIndexPaths(tmpArray, withRowAnimation: UITableViewRowAnimation.Top)
}
} else {
delegate?.rightItemSelected(selectedItem)
}
}
Since you know number of rows will be always 5 or 1, you can try something like this. However, this is not a standard approach, I would suggest to alter your datasource array.
Here is some example how to do it: http://www.nsprogrammer.com/2013/07/updating-uitableview-with-dynamic-data.html its for Objective-C but you will get the gist of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With