Search code examples
swiftuitableviewdesign-patternsdelegatescomposition

Why do we need to set delegate to self? Why isn't it defaulted by the compiler?


I think I fully understand the concept of delegation, my question is that when we do:

class someViewController : UIViewController, UITableViewDelegate{

}

would it ever be possible that we wouldn't want to set tableView.delegate to self?

If there isn't any chance then why is Xcode forcing us to do some extra work here?

If there is a chance that tableView.delegate is set to something other than self...well what is that? Can you please provide some examples?


Solution

  • When mentioning that tableView.delegate = self or tableView.dataSource = self in the desired ViewController, that's means the ViewController is saying "I am responsible for implementing those delegation/dataSource methods", means that this ViewController (self) is taking care of providing the needed method to let tableView knows how it should looks/behaves.

    Referring to your questions:

    would it ever be possible that we wouldn't want to set tableView.delegate to self?

    Actually it's possible, but this causes to let the tableView appears as an empty tableView (no rows in it), because no one is telling it about how it should looks/behave.

    If there is a chance that tableView.delegate is set to something other than self...well what is that? Can you please provide some examples?

    Yes you can, tableView.dataSource/delegate not necessary to be assigned to the same Viewcontroller that contains this tableView (but I find it more readable and understandable).

    For example:

    In the following code snippets, I assigning the dataSource of the tableView to another separated class (which is not even a UIViewController) on a different .swift file and it completely works fine:

    import UIKit
    
    // ViewController File
    class ViewController: UIViewController {
        var handler: Handler!
    
        @IBOutlet weak var tableView: UITableView!
        override func viewDidLoad() {
            super.viewDidLoad()
    
            handler = Handler()
            tableView.dataSource = handler
        }
    }
    

    Handler Class:

    import UIKit
    
    class Handler:NSObject, UITableViewDataSource {
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 10
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("myCell")
    
            cell?.textLabel?.text = "row #\(indexPath.row + 1)"
    
            return cell!
        }
    }
    

    The output works fine as it should.