I create a tableView inside a tableView inside another tableView. The problem is that when the cell is reused, the tableView inside another tableView is corrupted
I usually get that error
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 (2), 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).'
. How to create a cell in swift without the system of reuse ?
any help will be appreciated :)
private(set) let kNAME_CELL_FIRST = "Cell1"
private(set) let kNAME_CELL_SECOND = "Cell2"
private(set) let kNAME_CELL_THIRD = "Cell3"
private (set) var indexSelectedFirst : NSIndexPath!
weak var currentTableViewSecond : UITableView!
enum IDTableView : Int {
case kFIRST = 0
case kSECOND = 1
case kTHIRD = 2
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch tableView.tag {
case IDTableView.kFIRST.rawValue:
return self.categories.count
case IDTableView.kSECOND.rawValue:
return self.getItemSECOND()
case IDTableView.kTHIRD.rawValue:
return 1
default: return 0
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch tableView.tag {
case IDTableView.FIRST.rawValue :
if self.idSelectedSecond != -1 && self.indexSelectedFirst != nil && indexPath == self.indexSelectedFirst {
return HEIGHT_CELL_FIRST + (HEIGHT_CELL_SECOND * CGFloat(self.getItemSecond())) + HEIGHT_CELL_THIRD
}
else if self.indexSelectedCat != nil && indexPath == self.indexSelectedCat {
return HEIGHT_CELL_FIRST + (HEIGHT_CELL_SECOND * CGFloat(self.getItemSecond()))
}
return HEIGHT_CELL_FIRST
case IDTableView.SECOND.rawValue :
if self.indexSelectedSecond != nil && self.indexSelectedSecond == indexPath {
return HEIGHT_CELL_SECOND + HEIGHT_CELL_THIRD
} else {
return HEIGHT_CELL_SECOND
}
case IDTableView.THIRD.rawValue:
return HEIGHT_CELL_THIRD
default:
return 0
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch tableView.tag {
case IDTableView.FIRST.rawValue:
return self.tableViewFirst(tableView, cellForRowAtIndexPath: indexPath)
case IDTableView.Second.rawValue:
return self.tableViewSecond(tableView, cellForRowAtIndexPath: indexPath)
case IDTableView.THIRD.rawValue:
return self.tableViewThird(tableView, cellForRowAtIndexPath: indexPath)
default:
return UITableViewCell()
}
}
func tableViewFirst(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : firstTableViewCell = tableView.dequeueReusableCellWithIdentifier(kNAME_CELL_CAT, forIndexPath: indexPath) as firstTableViewCell
let item = self.arrFirst[indexPath.row]
cell.labelName.text = item.name
cell.imageView_.image = UIImage(named: "test.jpg")
cell.imageView_.clipsToBounds = true
cell.selectionStyle = UITableViewCellSelectionStyle.None;
if self.indexSelectedFirst != nil && indexPath == self.indexSelectedFirst {
cell.labelName.textColor = UIColor(rgb: 0xf1d3b6)
cell.tableViewSecond.hidden = false
} else {
cell.labelName.textColor = UIColor(rgb: 0xf1d3b6)
cell.tableViewSecond.hidden = true
}
return cell
}
func tableViewSecond(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : SecondTableViewCell = tableView.dequeueReusableCellWithIdentifier(kNAME_CELL_SECOND) as SecondTableViewCell
let itemParent = self.getSelectedItemFirstArray()!
let item = itemParent.arraySecond[indexPath.row]
cell.labelName.text = item.name
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func tableViewThird(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : ThirdTableViewCell = tableView.dequeueReusableCellWithIdentifier(kNAME_CELL_THIRD) as ThirdTableViewCell
cell.labelKey.text = "test string"
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
switch tableView.tag {
case IDTableView.FIRST.rawValue:
self.tableViewFirst(tableView, didSelectRowAtIndexPath: indexPath)
default:break
}
}
func tableViewFirst(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let lastIndexPath = self.indexSelectedFirst
self.closeCurrentSelectedItemK1 { (over: Bool) -> Void in
// JUST NEED TO CLOSE THE ITEM
if lastIndexPath != nil && lastIndexPath == indexPath { return }
let cell = tableView.cellForRowAtIndexPath(indexPath) as FirstTableViewCell
self.indexSelectedFirst = indexPath
self.currentTableSecond = cell.tableViewSecond
cell.tableViewSecond.hidden = false
UIView.animateWithDuration(0.6, animations: { () -> Void in
var indexPaths = [NSIndexPath]()
CATransaction.begin()
CATransaction.setCompletionBlock({ () -> Void in
self.tableViewFirst.beginUpdates()
self.tableViewFirst.endUpdates()
})
self.currentTableViewSecond.beginUpdates()
for i in 0...(self.getItemSecond()-1) {
indexPaths.append(NSIndexPath(forRow: i, inSection: 0))
}
self.currentTableViewSecond.insertRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.Bottom)
self.currentTableViewSecond.endUpdates()
CATransaction.commit()
}, completion: { (over: Bool) -> Void in })
}
}
func closeCurrentSelectedItemK1(completion : ((Bool)-> Void)) -> Void{
if self.indexSelectedFirst != nil {
var indexPaths = [NSIndexPath]()
UIView.animateWithDuration(0.3, animations: { () -> Void in
let cell = self.tableViewFirst.cellForRowAtIndexPath(self.indexSelectedFirst) as FirstTableViewCell
CATransaction.begin()
self.currentTableViewSecond.beginUpdates()
self.currentTableViewSecond.hidden = true
for i in 0...self.currentTableViewSecond.numberOfRowsInSection(0)-1 {
indexPaths.append(NSIndexPath(forRow: i, inSection: 0))
}
self.indexSelectedFirst = nil
/* IF SOME TO REMOVE */
if indexPaths.count > 0 {
self.currentTableViewSecond.deleteRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.Top)
}
self.currentTableViewSecond.endUpdates()
CATransaction.setCompletionBlock({ () -> Void in
self.tableViewFirst.beginUpdates()
self.tableViewFirst.endUpdates()
self.currentTableViewSecond = nil
self.indexSelectedFirst = nil
completion(true)
})
CATransaction.commit()
} else {
completion(true)
}
}