gorillka
8/1/2017 - 4:08 PM

Example of UITableViewDataSource and UITableViewDelegate using a enum for sections.

Example of UITableViewDataSource and UITableViewDelegate using a enum for sections.

extension ViewController: UITableViewDataSource, UITableViewDelegate {

  // As long as `total` is the last case in our TableSection enum,
  // this method will always be dynamically correct no mater how many table sections we add or remove.
  func numberOfSections(in tableView: UITableView) -> Int {
    return TableSection.total.rawValue
  }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // Using Swift's optional lookup we first check if there is a valid section of table.
    // Then we check that for the section there is data that goes with.
    if let tableSection = TableSection(rawValue: section), let movieData = data[tableSection] {
      return movieData.count
    }
    return 0
  }

  func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    // If we wanted to always show a section header regardless of whether or not there were rows in it,
    // then uncomment this line below:
    //return SectionHeaderHeight

    // First check if there is a valid section of table.
    // Then we check that for the section there is more than 1 row.
    if let tableSection = TableSection(rawValue: section), let movieData = data[tableSection], movieData.count > 0 {
      return SectionHeaderHeight
    }
    return 0
  }

  func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: SectionHeaderHeight))
    view.backgroundColor = UIColor(red: 253.0/255.0, green: 240.0/255.0, blue: 196.0/255.0, alpha: 1)
    let label = UILabel(frame: CGRect(x: 15, y: 0, width: tableView.bounds.width - 30, height: SectionHeaderHeight))
    label.font = UIFont.boldSystemFont(ofSize: 15)
    label.textColor = UIColor.black
    if let tableSection = TableSection(rawValue: section) {
      switch tableSection {
      case .action:
        label.text = "Action"
      case .comedy:
        label.text = "Comedy"
      case .drama:
        label.text = "Drama"
      case .indie:
        label.text = "Indie"
      default:
        label.text = ""
      }
    }
    view.addSubview(label)
    return view
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    // Similar to above, first check if there is a valid section of table.
    // Then we check that for the section there is a row.
    if let tableSection = TableSection(rawValue: indexPath.section), let movie = data[tableSection]?[indexPath.row] {
      if let titleLabel = cell.viewWithTag(10) as? UILabel {
        titleLabel.text = movie["title"]
      }
      if let subtitleLabel = cell.viewWithTag(20) as? UILabel {
        subtitleLabel.text = movie["cast"]
      }
    }
    return cell
  }

}