Zach
Zach

Reputation: 384

How do you add a second section with a different type of prototype cell to a tableview in Swift?

I have a tableview with 2 prototype cells in a view controller. I want each cell to display data from different arrays.

Below is my code. I can get the tableview to show jobs or schools, but not both. I don't understand how to make the table display cell1 (jobs) and then cell2 (schools) when each cell contains different data sources.

screenshot

Import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {


let jobs = ["McDonalds", "Hardees", "Taco Bell"]
let schools = ["Univ of CO", "Univ of TX", "Univ of CA"]


override func viewDidLoad() {
    super.viewDidLoad()

}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return jobs.count

}


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

        let cell = tableView.dequeueReusableCell(withIdentifier: "JobsCell", for: indexPath) as! Jobs

        let job = jobs[indexPath.row]
        cell.jobLbl.text = job

        return cell


    }

}

Answer: I fixed this by adding numberOfSections function (thanks Robert). Updated code below if anyone else has this question:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

let jobs = ["McDonalds", "Hardees", "Taco Bell"]
let schools = ["Univ of CO", "Univ of TX", "Univ of CA", "Univ of Camdenton"]


override func viewDidLoad() {
    super.viewDidLoad()
}


func numberOfSections(in tableView: UITableView) -> Int {
    return 2
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if (section == 0) {
        return jobs.count
    } else {
        return schools.count
    }

}


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

    if indexPath.section == 0 {

        let cell = tableView.dequeueReusableCell(withIdentifier: "JobsCell", for: indexPath) as! Jobs
        let job = jobs[indexPath.row]
        cell.jobLbl.text = job
        return cell

    } else {

        let cell = tableView.dequeueReusableCell(withIdentifier: "SchoolsCell", for: indexPath) as! Schools
        let school = schools[indexPath.row]
        cell.schoolLbl.text = school
        return cell

    }

}

}

Upvotes: 1

Views: 550

Answers (1)

Robert
Robert

Reputation: 6810

It sounds like you want to display one section with cells for jobs followed by a second section with cells for schools. If that's the case, you'll need to set the number of sections to 2, then rewrite your delegate functions to respond appropriately depending on the section number.

So numberOfRowsInSection is going to have to check the section number, then return the number of rows for that specific section. And cellForRowAt will need to check the section, then set up and return either a job or a school cell for the given row.

Here's what that would look like in your example:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    let jobs = ["McDonalds", "Hardees", "Taco Bell"]
    let schools = ["Univ of CO", "Univ of TX", "Univ of CA"]

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch(section) {
        case 0: return jobs.count
        default: return schools.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch(indexPath.section) {
        case 0:
            let cell = tableView.dequeueReusableCell(withIdentifier: "JobsCell", for: indexPath) as! Jobs
            let job = jobs[indexPath.row]
            cell.jobLbl.text = job
            return cell
        default:
            let cell = tableView.dequeueReusableCell(withIdentifier: "SchoolsCell", for: indexPath) as! Schools
            let school = schools[indexPath.row]
            cell.schoolLbl.text = school
            return cell
        }
    }

}

And here's the output in the simulator:

Simulator output image

Upvotes: 1

Related Questions