Delegate and Datasource in different classes possible? - UITableView Delegate and Datasource in different classes possible? - UITableView objective-c objective-c

Delegate and Datasource in different classes possible? - UITableView


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: Cellclass 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 Controllerclass 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: TableViewDelegateprotocol 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 DataSourceclass 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    }}


Yes you can have them in separate classes. They are normally in the same class because you may need to use data(like array) inside delegate methods like in didSelectRowAtIndexPath:

Tableview and Collectionview Datasource and Delegates are based on Delegate design pattern, where you can delegate some work to other objects.

Why do you need two different protocols?

Because datasource is used to provide data that controls the state of the tableview/collectionview whereas delegate supplies behaviour and controls how to use the data.


in some Special Situation, i will use two different class to realize the delegate and the dataSource method.

for example:

in my project, some data contain by a instance(let's call it Global user), such as user's article, user's comment, user's product...

i make a instance Class for the Global user. in this class , i have some NSMutableArray for user's data,when user login success.i request his data from my data server and store in these data Array.

After that, when the user want to look his product, he will click some button like my product, then push to MyProductListVC, in the MyProductListVC, i have a tableView init to show his products, but i don't want to request his products data from my data server again, because i have all his product data in my Global user Class,so i make the tableView's dataSource to the Global user class, and make the delegate to the MyProductListVC, and this logic works fine on my project for a long time. this is how i define delegates and datasources in diffrent classes.

About your second question:

Why we need seperation as delegates and datasources?

i answered this question based on my project, first ,i want all user's data focus on one Class, this way convenient for me to manage the user's data. second , when i need to change how show the data in the view, i only need to change the code in MyProductListVC.

Here's what I think is the most important:

i can put all request method in my Global user's Class, i don't want too many request code in my MyProductListVC and any other VC, because in my project, the VC only need to show data, don't need to request.