2

Ich arbeite mich durch BigNerdRanch iOS-Programmierung. Im Moment arbeite ich an der Bronze Herausforderung in Kapitel 11 (Subclassing UITableViewCell)Ändern von UITableViewCell, wo soll dieser Code platziert werden? Verwirrt über Designmuster

Herausforderung:

Aktualisieren der ItemCell die valueInDollars in grün angezeigt werden, wenn der Wert kleiner als 50 ist und rot, wenn der Wert größer ist als oder gleich 50

Meine Lösung ist:

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

Nun stellte ich diese Logik in meinem ItemsViewController (UITableViewController), Tableview (cellForRowAtIndexPath) -Funktion.

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

Ist es besser Praxis die Logik in der Steuerung oder in der ItemCell Klasse wie solche zu platzieren?

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

}

Im vorigen Kapitel sprachen sie über Dependency Inversion Principle und Design Patterns wie MVC und Dependency Injection. Ist dies eine Anwendung eines dieser Konzepte? Mit Injection Dependency erwähnen sie, dass Sie nicht möchten, dass ein Objekt annimmt, welche Objekte auf niedrigerer Ebene verwendet werden müssen. Verwechsle ich dieses Designmuster mit Model View Controller, wo die Zelle nichts über die Logik des Inhalts wissen sollte? Ich versuche, all diese Konzepte und Muster zu verstehen und em zu identifizieren.

Antwort

2

Meiner Meinung nach, wenn ItemCell speziell für die Anzeige einer Item ausgelegt ist, sollten Sie wahrscheinlich die Logik in ItemCell setzen. Wenn ItemCell nicht speziell zur Anzeige von Item s vorgesehen ist und auch andere Daten angezeigt werden können, setzen Sie die Logik in den Controller.

Ich weiß nicht, ob Sie das bemerkt haben, aber einige UIView Unterklassen haben Logik! UISegmentedControl muss das ausgewählte Segment abwählen, wenn der Benutzer ein anderes Segment auswählt. UIButton "leuchtet" ein wenig, wenn angetippt wird. UIPickerView macht einen Ton beim Scrollen. Die Ansichten haben Logik, denn dafür sind sie gedacht! UISegementedControl funktioniert wie Registerkarten, daher muss das ausgewählte Segment abgewählt werden, wenn ein anderes Segment ausgewählt wird!

Also, wenn Ihre ItemCell ist speziell entwickelt, um eine Item anzuzeigen, dann können Sie die Logik in ItemCell setzen.

Allerdings denke ich, dass Sie keine Methode dafür erstellen sollten. Eine Eigenschaft wäre besser:

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

Und dann können Sie tun es einfach so:

cell.valueInDollars = item.valueInDollars 

Hinweis: Sie müssen auch valueInDollars in der ItemCell ‚s initializer initialisieren, oder Sie können einfach machen es ist optional.

+0

danke für die Rückmeldung! – gofly

+0

Wenn Sie denken, dass meine Antwort Ihnen geholfen hat, denken Sie bitte daran, die Antwort zu akzeptieren, indem Sie auf dieses Häkchen klicken. @ user2521203 – Sweeper

0

nur für die nächsten Benutzer zu vereinfachen, die 3 auf Swift sind, wäre die Lösung gewesen:

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

zu ItemCell.swift und

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

mit

ersetzen hinzugefügt

cell.valueInDollars = item.valueInDollars

in ItemsVieController.swift.