Mirza Delic
Mirza Delic

Reputation: 4339

Swift configure custom cell

I have this code in uitableview controller:

var results: [Item] = []
...
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("OrderCell") as! OrderTableViewCell!
    cell.item = results[indexPath.row]
    return cell
}

and OrderTableViewCell.swift:

class OrderTableViewCell: UITableViewCell {


    var item: Item! {
        didSet {
            self.setupCell()
        }
    }

    @IBOutlet var itemNo: UILabel!
    @IBOutlet var itemPrice: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

    func setupCell() {
        itemNo.text = order.document_no
        itemPrice.text = order.sum
    }

}

Now, i need to know is this good way to setup cell(with didSet), or it is better to fill this fields itemNo and itemPrice from uitableview controller?

Upvotes: 0

Views: 3318

Answers (2)

Sam Falconer
Sam Falconer

Reputation: 488

IMHO, this is better than adding view-dependent logic to your UITableViewController.

iOS apps frequently utilize the "model-view-controller" pattern, which you have here. While the details of this pattern can vary, it is generally considered a good thing to have "loosely coupled" components. Meaning, the controller shouldn't be concerned with which table cell (view) labels are showing what model information.

Additionally, encapsulating your logic like this inside of the view like this sets you up to cleanly observe updates to Item (your model) in the future (completely eliminating the need for additional controller interaction). You could accomplish this automatic updating via something like Key-Value Observing.

The Wikipedia page on MVC has an excellent graphic to explain how the components typically interact.

Source: https://en.wikipedia.org/wiki/Model–view–controller#Description

Upvotes: 2

Andrew McKinley
Andrew McKinley

Reputation: 1137

It seems to me that it would be better done like so:

func setupCell(_data:DataObject) {
    // update layout depending on data
    itemNo.text = _data.document_no 
    itemPrice.text = _data.sum
}

Using this:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// this way avoids forced unwrapping. much safer   
if let cell = tableView.dequeueReusableCellWithIdentifier("OrderCell") as? OrderTableViewCell{
        cell.setupCell(results[indexPath.row])
        return cell
    }
    return UITableViewCell()
}

Keep in mind that because of dequeueReusableCellWithIdentifier the tableview is reusing the instances of the cell. Every time a cell is displayed cellForRowAtIndexPath is called over again and that cell needs to be laid out again. You don't its data to be permanent.

Upvotes: 1

Related Questions