Модификация UITableViewCell, где разместить этот код? Запутался в шаблонах дизайна

ios swift design-patterns model-view-controller dependency-injection

112 просмотра

2 ответа

68 Репутация автора

Я работаю над BigNerdRanch iOS-программированием. В настоящее время я работаю над бронзовым вызовом в главе 11 (создание подклассов UITableViewCell)

Вызов:

Обновите ItemCell, чтобы отображать valueInDollars зеленым цветом, если значение меньше 50, и красным, если значение больше или равно 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 и внедрение зависимостей. Это применение одного из этих понятий? В зависимости от инъекций они упоминают, что вы не хотите, чтобы объект предполагал, какие объекты более низкого уровня им нужно использовать. Не путаю ли я этот шаблон проектирования с Model View Controller, где ячейка не должна ничего знать о логике содержимого? Я пытаюсь обернуть голову вокруг всех этих концепций и моделей и быть в состоянии идентифицировать их.

Автор: gofly Источник Размещён: 17.07.2016 11:53

Ответы (2)


2 плюса

90040 Репутация автора

Решение

На мой взгляд, если ItemCellспециально разработан для отображения Item, вы, вероятно, должны ввести логику ItemCell. Если ItemCellон специально не предназначен для отображения Items, и его также можно использовать для отображения других вещей, поместите логику в контроллер.

Я не знаю, заметили ли вы это, но у некоторых UIViewподклассов есть логика! UISegmentedControlнеобходимо отменить выбор выбранного сегмента, когда пользователь выбирает другой сегмент. UIButtonнемного светится при постукивании. 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инициализаторе, или вы можете просто сделать его необязательным.

Автор: Sweeper Размещён: 18.07.2016 01:34

0 плюса

1633 Репутация автора

просто для упрощения для следующих пользователей 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 .

Автор: nyxee Размещён: 26.05.2017 02:03
Вопросы из категории :
32x32