vishalwaka
vishalwaka

Reputation: 89

Use different type of cells and different number of rows in UITableViewController

I am trying to use a UITableViewController(Static table view) with 4 sections and each has a different type of cell.

The number of cells in a section depends on the data received from the web service. In the storyboard, I have created one type of cell in each section.

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // Number of rows in attachment sect
    if section == 2 {
        guard let currentDataModel = dataModel else { return 0 }
        return currentDataModel.attachments.count
    }
    else if section == 3 {
        guard let currentDataModel = dataModel else { return 0 }
        return currentDataModel.contacts.count
    }
    return super.tableView(tableView, numberOfRowsInSection: section)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let currentSection = indexPath.section
    if currentSection == 2 {

        let currentRow = indexPath.row
        let cell = tableView.dequeueReusableCell(withIdentifier: "attachmentCell", for: indexPath) as! AttachmentViewCell
        cell.setDataForCell(dataModel: dataModel?.attachments[currentRow], indexPath: indexPath)
        return cell
    }
    //Show cells for Contact Section
    else if currentSection == 3 {
        let currentRow = indexPath.row
        let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactViewCell
        cell.setDataForCell(dataModel: dataModel?.contacts[currentRow], indexPath: indexPath)
        return cell
    }
    return super.tableView(tableView, cellForRowAt: indexPath)
}

I am getting this error while calling dequeueReusableCellWithIdentifier:forIndexPath:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'

Can I Use the different type of cells and a different number of rows in each section in a UITableViewController?

Upvotes: 1

Views: 133

Answers (1)

Niroj
Niroj

Reputation: 1114

Can you try this.If need a four sections then return 4 in numberofsections. You can add the title to each sections as below and later add it to label in viewForHeaderInSection.You must provide the number of rows in each sections correctly.

override func numberOfSectionsInTableView(tableView: UITableView) -> Int
    {
        return 4
    }


    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if(section == 0)
        {
            return "Section 0"
        }
        else if(section == 1)
        {
            return "Section 1"
        }
        else if(section == 2)
        {
            return "section 2"
        }
        else if(section == 3)
        {
            return "section 3"
        }
        return ""
    }

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows

        switch(section)
        {
        case 0: //for first section
            //return your count

        case 1://Cells for

            //return your count

        case 2:

            //return your count

        case 3:
          //return your count

        default:
            return 4
        }

    return 0
}

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.section == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! Cell1

            return cell 

        } 
    else if indexPath.section == 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! Cell1

            return cell 

        }

 else if indexPath.section == 2 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! Cell1

            return cell 

        }

 else if indexPath.section == 3 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! Cell1

            return cell 

        }
else {

            let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as? Cell2
            //Set up labels etc.
            return cell!
        }
    }

 override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 50))
    headerView.layer.borderWidth = 2
    let myLabel = UILabel()
    myLabel.frame = CGRectMake(0, 0, tableView.frame.width - 70, 50)
    myLabel.font = UIFont.boldSystemFontOfSize(18)
    myLabel.textColor = UIColor.whiteColor()
    myLabel.textAlignment = .Left
    myLabel.text = "  " + self.tableView(tableView, titleForHeaderInSection: section)!
    headerView.addSubview(myLabel)
    return headerView
}

If you are using .xib file then you should also register that file in viewDidLoad() as

self.tableView.registerNib(UINib(nibName: "cell1", bundle: nil), forCellReuseIdentifier: "cell1")

self.tableView.registerNib(UINib(nibName: "cell2", bundle: nil), forCellReuseIdentifier: "cell2")

Upvotes: 1

Related Questions