Nick89
Nick89

Reputation: 2998

How to create a Grouped TableView with sections programmatically in Swift

I would like to know how to create a grouped/sectioned tableview programmatically. The design I am trying to create is this:

enter image description here

I want there to be a UIImageView at the top with a 160 height, followed by 3 sections, each with a different number of rows. I will then place static labels in each row and then update their labels with my data.

My code for this VC is as follows:

import UIKit

class SelectedFilmTableViewController: UITableViewController {

var film: Film? {
    didSet {
        navigationItem.title = film?.Film_Name
    }
}

var cellId = "cellId"

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self
    tableView.delegate = self
    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: cellId)

}

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

    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier(cellId, forIndexPath: indexPath) as UITableViewCell

    cell.textLabel?.text = film?.Directed_By
    cell.detailTextLabel?.text = film?.Film_Poster_Image_URL

    return cell

}

}

I have tried adding the method to state the numberOfSections etc but I don't seem to see them when I build the app. All I see is a normal looking tableview. Am I missing some setup?

Because I am navigating to this VC programmatically, I need to set this up without using the storyboard.

Any help on how to create the look I need above is appreciated, thanks!

Upvotes: 6

Views: 30143

Answers (3)

Brian Gorman
Brian Gorman

Reputation: 824

When combining other views with a TableView I prefer to make a UIViewController and use a UITableViewController as an embedded controller.

I committed an example on github check it out

Here is what your table controller code should look like:

class MyTableController : UITableViewController {
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 3
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if(section == 2) {
            return "Film Information"
        } else {
            return " "
        }
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if(section == 0) {
            return 1
        } else if(section == 1) {
            return 2
        } else {
            return 4
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("SomeCell", forIndexPath: indexPath) as UITableViewCell


        return cell

    }
}

Upvotes: 9

chiarotto.alessandro
chiarotto.alessandro

Reputation: 1589

First you should return 3 section using the following method

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

and then according to the section number passed to this method return 1,2 and 4 (rows) for each section:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // return if section == 0 return 1 and so on...
}

finally use indexPath passed to this method to return the appropriate content according to section and row stored in indexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier(cellId, forIndexPath: indexPath) as UITableViewCell

  // if indexPath.section == 0 {
  //  cell.textLabel?.text = film?.Directed_By
  //  cell.detailTextLabel?.text = film?.Film_Poster_Image_URL
  // } else if ....


    return cell

}

Upvotes: 1

Avt
Avt

Reputation: 17043

You forgot to call reloadData. Update viewDidLoad method to

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self
    tableView.delegate = self
    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: cellId)
    tableView.reloadData()
}

If you need 3 sections with different number of rows change your methods to

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

    return 3
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return [1,2,4][section]
}

To add an image to the top use UITableView's property tableHeaderView.

Upvotes: 0

Related Questions