22
votes

This is a fairly simple question I think. I've separated my UITableView delegate / data sources into their own extensions

//MARK: - UITableView Data Source/Delegate

extension TweetsViewController: UITableViewDataSource {
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 0
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! TweetCell
        return cell
    }
}

However in the view controller itself I need to set the tblView delegate

class TweetsViewController : UIViewController {

    @IBOutlet weak var tblView: UITableView!


    var fetchedResultsController : NSFetchedResultsController!

    //MARK: View Management

    override func viewDidLoad() {
        super.viewDidLoad()

        tblView.dataSource = self


    }
}

However, since the view controller is nor conforming to the protocols but having the extensions handle them, then how do I explicitly set the datasource and delegate for the tableView? Thanks!

4

4 Answers

35
votes

You can divide in a extension, as you can check in the apple documentation section about Extensions handling Protocols.

Here I have implement a minimum code doing what you ask, check it out.

  import UIKit


class TableViewViewController: UIViewController {
    @IBOutlet weak var table: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        table.delegate = self
        table.dataSource = self
    }
}

extension TableViewViewController: UITableViewDelegate,UITableViewDataSource {

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
        cell.textLabel!.text = "it works"
        return cell
    }

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

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

In Swift 3 and above the table view datasource and delegate methods changed.

import UIKit

class HomeViewController: UIViewController {

  @IBOutlet var tblPropertyList: UITableView!
  // MARK: - View Life Cycle
  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    tblPropertyList.delegate = self
    tblPropertyList.dataSource = self
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
}

// MARK: - Table View DataSource
extension HomeViewController: UITableViewDataSource {

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath as IndexPath)
    cell.textLabel!.text =  "\(indexPath.row) - Its working"
    return cell
  }

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

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

// MARK: - Table View Delegate
extension HomeViewController: UITableViewDelegate {

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let indexPath = tableView.indexPathForSelectedRow
    let currentCell = tableView.cellForRow(at: indexPath!)!
    print(currentCell.textLabel!.text!)

  }
}
7
votes

the view controller is nor conforming to the protocols but having the extensions handle them

This is incorrect. The extension makes the view controller conformant to the protocols, and the data source and delegate can be set as usual, e.g.: self.tableView.delegate = self

0
votes

Now in Swift 5.1 you don't need to inherit UITableViewDelegate and UITableViewDataSource

extension HomeViewController {

// MARK: - Table View DataSource

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath as IndexPath)
    cell.textLabel!.text =  "\(indexPath.row) - Its working"
    return cell
  }

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

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

// MARK: - Table View Delegate

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let indexPath = tableView.indexPathForSelectedRow
    let currentCell = tableView.cellForRow(at: indexPath!)!
    print(currentCell.textLabel!.text!)

  }
}