修改UITableViewCell,放置此代码的位置?对设计模式感到困惑

时间:2016-07-17 23:53:56

标签: ios swift design-patterns model-view-controller dependency-injection

我正在通过BigNerdRanch iOS编程工作。我目前正在进行第11章中的青铜挑战(Subclassing UITableViewCell)

挑战:

如果值小于50,则更新ItemCell以显示绿色的valueInDollars;如果值大于或等于50,则显示红色。

我的解决方案是:

cell.valueLabel.textColor = item.valueInDollars < 50 ? UIColor.redColor() : UIColor.greenColor()

现在我把这个逻辑放在我的ItemsViewController(UITableViewController),tableView(cellForRowAtIndexPath)函数中。

// 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

将逻辑放在控制器或ItemCell类中更好吗?

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()
}

}

在前一章中,他们讨论了依赖倒置原则和设计模式,如MVC和依赖注入。这是其中一个概念的应用吗?通过注入依赖性,他们提到您不希望对象假设他们需要使用哪些较低级别的对象。我是否将这种设计模式与模型视图控制器相混淆,而Cell不应该对内容的逻辑有所了解?我试图围绕所有这些概念和模式,并能够识别出他们。

2 个答案:

答案 0 :(得分:2)

在我看来,如果ItemCell专门用于显示Item,那么您应该将逻辑放在ItemCell中。如果ItemCell没有专门用于显示Item,并且它也可以用于显示其他内容,那么将逻辑放在控制器中。

我不知道你是否注意到这一点,但有些UIView子类有逻辑!当用户选择其他细分时,UISegmentedControl需要取消选择所选细分。 UIButton&#34;发光&#34;点击时一点点。滚动时UIPickerView发出声音。视图具有逻辑性,因为它就是它们的设计目标! UISegementedControl旨在像标签一样工作,因此当选择另一个细分时,必须取消选择所选的细分

因此,如果您的ItemCell专门用于展示Item,那么您可以将逻辑放在ItemCell中。

但是,我认为你不应该为此创建一个方法。财产会更好:

var valueInDollars: Int {
    willSet {
        self.valueLabel.text = "$\(newValue)"
        self.valueLabel.textColor = newValue < 50 ? UIColor.redColor() : UIColor.greenColor()
    }
}

然后你就可以这样做:

cell.valueInDollars = item.valueInDollars

注意:您还需要在valueInDollars的初始化程序中初始化ItemCell,或者您可以将其设为可选项。

答案 1 :(得分:0)

为了简化Swift 3上的下一个用户,解决方案应该是:

var valueInDollars: Int = 0 {
   willSet {
      self.valueLabel.text      = "$\(newValue)"
      self.valueLabel.textColor = newValue < 50 ? UIColor.red : UIColor.green
   }
}

添加到 ItemCell.swift 并替换

cell.valueLabel.text = "$\(item.valueInDollars)"

cell.valueInDollars = item.valueInDollars

ItemsVieController.swift 中的