Delegate and Datasource in different classes possible? - UITableView

Viewed 2069

While using UITableView there are two types of methods ie, datasource and delegates still both supposed to be connected to the same parent view controller class.

Is there any way to define delegates and datasources in diffrent classes?

Why we need seperation as delegates and datasources?

Note: This question applies to UICollectionView and similar Objects

4 Answers

As explained well enough about the delegation pattern in other responses, we can declare tableview Datasource and Delegate as different objects in order to avoid Massive ViewControllers and to achieve lean ViewControllers .

Here is a code example Using Delegate Design pattern .

import UIKit

// MARK: Cell

class ItemCell: UITableViewCell{
    var label: UILabel!
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 20))
        label.textColor = .black
        label.backgroundColor = .yellow
        contentView.addSubview(label)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// MARK: Main View Controller

class BlueViewController: UIViewController{

    var tableView: UITableView!
    var myDataSourse: MyTVDataSource!
    var myDelegate: MyTVDelegate!


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .blue
        tableView = UITableView()
        myDataSourse = MyTVDataSource(tableView: tableView)
        myDelegate = MyTVDelegate()
        myDelegate.presentingController = self
        tableView.dataSource = myDataSourse
        tableView.delegate = myDelegate
        tableView.register(ItemCell.self, forCellReuseIdentifier: "Cell")

        self.view.addSubview(tableView)



        self.tableView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0)
            ])
    }
}
extension BlueViewController: BluePresenting{
    func currentSelected(_ indexPath: IndexPath) {
        print(indexPath)
    }


}

// MARK: TableViewDelegate


protocol BluePresenting: class {
    func currentSelected(_ indexPath: IndexPath)
}

class MyTVDelegate: NSObject,UITableViewDelegate{

   var presentingController: BluePresenting?

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            presentingController?.currentSelected(indexPath)
    }
}

// MARK: TableView DataSource


class MyTVDataSource: NSObject, UITableViewDataSource{
    private var tableView: UITableView
    private var items = ["Item 1","item 2","item 3","Item 4"]

    init(tableView: UITableView) {
        self.tableView = tableView
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count

    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = ItemCell(style: .default, reuseIdentifier: "Cell")
        cell.label.text = items[indexPath.row]

        return cell
    }

}
Related