I'm working my way through BigNerdRanch iOS Programming. I'm currently working on the Bronze challenge in Chapter 11 (Subclassing UITableViewCell)
Challenge:
Update the ItemCell to display the valueInDollars in green if the value is less than 50 and red if the value is greater than or equal to 50.
My solution is:
cell.valueLabel.textColor = item.valueInDollars < 50 ? UIColor.redColor() : UIColor.greenColor()
Now I placed this logic in my ItemsViewController (UITableViewController), tableView(cellForRowAtIndexPath) function.
// Get a new or recycled cell
let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell", forIndexPath: indexPath) as! ItemCell
// Update the labels for the new preferred text size
cell.updateLabels()
if (itemStore.allItems.count == indexPath.row) {
cell.nameLabel.text = "No more items!"
cell.serialNumberLabel.text = ""
cell.valueLabel.text = ""
} else {
// Set the test on the cell with the description of the item
// that is at the nth index of items, where n = row this cell
// will appear in on the tableview
let item = itemStore.allItems[indexPath.row]
cell.nameLabel.text = item.name
cell.serialNumberLabel.text = item.serialNumber
cell.valueLabel.text = "$\(item.valueInDollars)"
cell.valueLabel.textColor = item.valueInDollars < 50 ? UIColor.redColor() : UIColor.greenColor()
}
return cell
Is it better practice to place the logic in the controller or in the ItemCell class like such?
class ItemCell: UITableViewCell {
@IBOutlet var nameLabel: UILabel!
@IBOutlet var serialNumberLabel: UILabel!
@IBOutlet var valueLabel: UILabel!
func updateLabels() {
let bodyFont = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
nameLabel.font = bodyFont
valueLabel.font = bodyFont
let caption1Font = UIFont.preferredFontForTextStyle(UIFontTextStyleCaption1)
serialNumberLabel.font = caption1Font
}
func updateValueTextColor(forValue value: Int) {
valueLabel.textColor = value < 50 ? UIColor.redColor() : UIColor.greenColor()
}
}
In the previous chapter they talked about Dependency Inversion Principle and Design Patterns like MVC and Dependency Injection. Is this an application of one of these concepts? With Injection Dependency they mention that you don't want an object to assume which lower-level objects they need to use. Am I confusing this design pattern with Model View Controller where the Cell shouldn't know anything about the logic of the content? I'm trying to wrap my head around all these concepts and patterns and be able to identify em.
In my opinion, if ItemCell
is specifically designed for displaying an Item
, you should probably put the logic in ItemCell
. If ItemCell
is not specifically made to display Item
s, and it can also be used to display other stuff, then put the logic in the controller.
I don't know whether you noticed this, but some UIView
subclasses have logic! UISegmentedControl
needs to deselect the selected segment when the user selects another segment. UIButton
"glows" a little bit when tapped on. UIPickerView
makes a sound when scrolled. The views have logic because that is what they are designed for! UISegementedControl
is designed to work like tabs, so the selected segment must be deselected when another segment is selected!
So if your ItemCell
is specifically designed to display an Item
, then you can put the logic in ItemCell
.
However, I think that you shouldn't create a method for this. A property would be better:
var valueInDollars: Int {
willSet {
self.valueLabel.text = "$\(newValue)"
self.valueLabel.textColor = newValue < 50 ? UIColor.redColor() : UIColor.greenColor()
}
}
And then you can just do it like this:
cell.valueInDollars = item.valueInDollars
Note: you also need to initialize valueInDollars
in the ItemCell
's initializer, or you can just make it optional.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments