Silverlaine Silverlaine - 6 months ago 23
iOS Question

Swift generic closure

I'm building a library for static table views and it works fine, but I encountered a problem with generic closures.

It looks like this so far:

orderForm = Form(tableView: orderTable) { f in
f.section { s in
s.footer("Při platbě nejsou účtovány žádné další poplatky.")
s.cell("Selection")
.configure { (cell, path) in
let c = cell as! ProfileSelectionCell
c.titleLabel?.text = "Způsob platby"
c.detailLabel?.text = self.paymentType.first
}
s.cell("Selection")
.configure { (cell, path) in
let c = cell as! ProfileSelectionCell
c.titleLabel?.text = "Balíček"
c.detailLabel?.text = "20 kr. za 1000 Kc"
}.selected { path in

}
}
}


I wanna have the "cell" variable already cast to appropriate type, in this case ProfileSelectionCell.

Here is the source for the cell class:

class Cell {
internal let id: String
internal var configure: ((cell: UITableViewCell, path: NSIndexPath) -> Void)?
internal var selected: ((path: NSIndexPath) -> Void)?

init(id: String) {
self.id = id
}

func configure(config: ((cell: UITableViewCell, path: NSIndexPath) -> Void)?) -> Self {
self.configure = config
return self
}

func selected(selected: (path: NSIndexPath) -> Void) -> Self {
self.selected = selected
return self
}}


My problem is that if I make the configure method generic, it is not possible to store the config closure to the cell variable and if I make the whole cell generic, I can't save the cell to an array in Section class and so on..

Is this solvable in any way?

Answer

You can make the Cell class generic, e.g.

class Cell<T : UITableViewCell> {
}

and then use T instead of every UITableViewCell.

Unfortunately you would have to have the same in both Section and Form classes, too. That would work for tables with one type of cells but it won't probably work for tables with multiple cell types. In that case you will always need casting somewhere.

Comments