Dynamic datasource/delegates for UITableView in swift

I need to set up different objects based on certain conditions as the datasource & delegate for table view.

But I am not able to assign tableview’s datasource/delegate as it throws some errors.

  • CString from NSData
  • Proximity sensor in Swift (from Objective-C)
  • Iterating over an NSOrderedSet
  • What is the type of the logical operators?
  • How to copy SKSpriteNode with SKPhysicsBody?
  • How do I condense unwrapping multiple optionals in Swift?
  • Cannot assign a value of type NSObject? to a value of type UITableViewDelegate?

    I did check this Q&A but this did not work.

    var dataSourceDelegate:NSObject?
    class RootViewController: UIViewController {
    ...
    override func viewDidLoad() {
            dataSourceDelegate = TableDataSourceDelegate()
            // Table View
            tableView = UITableView()
            tableView!.setTranslatesAutoresizingMaskIntoConstraints(false)
            tableView!.dataSource = dataSourceDelegate 
            // Cannot assign a value of type NSObject? to a value of type UITableViewDataSource?
            tableView!.delegate = dataSourceDelegate
            // Cannot assign a value of type NSObject? to a value of type UITableViewDelegate?
            view.addSubview(tableView!)
    
            // Constraints
            var views:[String:UIView] = ["table":tableView!]
            var hTableConstraint = "H:|[table]|"
            var vConstraint = "V:|[table]|"
            view.addConstraintsToView([hTableConstraint, vConstraint], view: view, viewVariables: views)
        }
    ...
    }
    

    This is the datasource/delegate class

    class TableDataSourceDelegate:NSObject, UITableViewDataSource, UITableViewDelegate {
        // MARK: Datasource
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 0
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            return UITableViewCell()
        }
    
        // MARK: Delegates
    }
    

    2 Solutions Collect From Internet About “Dynamic datasource/delegates for UITableView in swift”

    NSObject? doesn’t conforms to UITableViewDelegate, neither to UITableViewDataSource. You should create your protocol like

    protocol GeneralDataSource: UITableViewDataSource, UITableViewDelegate {}
    

    And then all data sources should conform that protocol.

    class MyDataSource: NSObject, GeneralDataSource {
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            return UITableViewCell()
        }
    
        func numberOfSectionsInTableView(tableView: UITableView) -> Int {
            return 2
        }
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 1
        }
    }
    

    Then you can use it like this

    var myDataSource: GeneralDataSource?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.myDataSource = MyDataSource()
        self.tableView.delegate = self.myDataSource
    }
    

    This is how your TableDataSourceDelegate should look like:

    import UIKit
    
    class TableDataSourceDelegate: NSObject {
    }
    
    extension TableDataSourceDelegate: UITableViewDataSource {
        @objc func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 0
        }
    
        @objc func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "defaultCell")
            cell.textLabel?.text = "test"
            return cell
        }
    }
    
    extension TableDataSourceDelegate: UITableViewDelegate {
        // your delegate implementation here
    }
    

    And view controller implementation

    import UIKit
    
    // The typealias definition
    typealias TVDataSourceDelegate = protocol<UITableViewDataSource, UITableViewDelegate>
    
    class ViewController: UIViewController {
    
        var dataSourceDelegate: TVDataSourceDelegate?
        var tableView: UITableView?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            dataSourceDelegate = TableDataSourceDelegate()
            // Table View
            tableView = UITableView()
            tableView!.translatesAutoresizingMaskIntoConstraints = false
            tableView!.dataSource = dataSourceDelegate
            tableView!.delegate = dataSourceDelegate
            view.addSubview(tableView!)
    
            // other code ...
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    

    Although, I would recommend to separate dataSource and delegate objects (e.g. put the delegate protocol conforming code into your view controller’s code.