Vkharb Vkharb - 5 months ago 83
iOS Question

Want to redefine willDisplayCell method in Swift. How to redefine class methods

I am using certain UI components within my custom cell class and I want to configure those in the willDisplayCell method. The original definition is

public func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)


Now using
cell.myTextField.text = "customise"

gives out error that cell does not have any component as myTextField

to resolve this I will have to redefine the method to

public func tableView(tableView: UITableView, willDisplayCell cell: **myCustomCellClass**, forRowAtIndexPath indexPath: NSIndexPath)


Any leads on how to do this and subsequently how to redefine any present class methods in swift will be great. Thanks in advance.

Answer

Unfortunately, you cannot change the parameter type because that would change the interface. You could get away with changing the return type of a method to a subtype but you cannot change method parameter to a subtype.

You have one option really, a dynamic cast:

public func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
   // use as? or as! to cast UITableViewCell to your desired type
}

Of course, you can do the same in multiple ways, for example, you can create a redirection method:

public func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
   self.tableView(tableView, willDisplayMyCell: cell as! MyCellClass, forRowAtIndexPath: indexPath)
}

private func tableView(tableView: UITableView, willDisplayMyCell myCell: MyCellClass, forRowAtIndexPath indexPath: NSIndexPath) {
   // do something
}

and you can abstract that into a subprotocol of UITableViewDelegate:

class MyTableViewCell : UITableViewCell {

}

protocol MyTableViewDelegate : UITableViewDelegate {
    associatedtype CellClass: UITableViewCell

    func tableView(
        tableView: UITableView,
        willDisplayMyCell cell: CellClass,
        forRowAtIndexPath indexPath: NSIndexPath)
    }

extension MyTableViewDelegate {
    func tableView(
        tableView: UITableView,
        willDisplayCell cell: UITableViewCell,
        forRowAtIndexPath indexPath: NSIndexPath) {

        self.tableView(tableView, willDisplayMyCell: cell as! CellClass, forRowAtIndexPath: indexPath)
    }    
}

The cool thing about this is that the protocol is reusable, however, it all boils down to as? or as! dynamic cast.

Comments