Swift UITableviewcell without reuse

1k Views Asked by At

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)
    }
}
0

There are 0 best solutions below