0

Ich habe eine benutzerdefinierte UICollectionViewCell, von der ich versuche, einen Wert an meinen View-Controller zu übergeben. Ich bin in der Lage, ein Bild an die Zelle zu übergeben, aber alles andere kommt bei der Initialisierung auf Null.Wie übermittle ich einen Wert an eine benutzerdefinierte UICollectionViewCell?

Relevante Code im View-Controller:

override func viewDidLoad() { 

    self.collectionView!.registerClass(MyCustomCell.self, forCellWithReuseIdentifier: "Cell") 

} 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! MyCustomCell 

    cell.someValue = 5 
    cell.imageView.image = UIImage(named: "placeholder.png") 

    return cell 

} 

In der benutzerdefinierten Zellklasse:

var someValue: Int! 
var imageView: UIImageView! 

override init(frame: CGRect) { 

    super.init(frame: frame) 

    imageView = UIImageView(frame: CGRectMake(0, 0, frame.width, frame.height)) 
    contentView.addSubview(imageView) 

    let someValueLabel = UILabel() 
    someValueLabel.frame = CGRectMake(0, 75, 200, 30) 
    someValueLabel.text = "Value is: \(someValue)" 
    self.addSubview(someValueLabel) 
} 

Das Bild vom UICollectionView erfolgreich vorbei ist, und ich bin in der Lage, um sie anzuzeigen, aber ‚somevalue 'ist immer Null.

Was mache ich falsch?

+0

Auch sollten Sie nicht Ihre UIImageView-Eigenschaft "ImageView" aufrufen. Seit UITableViewCell enthält bereits eine mit diesem Namen. Dies könnte zu unerwünschten Effekten führen. Vielleicht ist es behoben worden, aber ich habe schon einige Probleme erlebt. Wie folgt Q: http://stackoverflow.com/questions/11681273/uitableviewcell-imageview-changing-on-select – BoilingLime

Antwort

2

Die Methode init wird viel früher aufgerufen, als Sie denken - innerhalb des Prozesses dequeue - wenn das Zellenobjekt erstellt wird. Teil des Initialisierungsprozesses ist das Anfügen der in Storyboard entworfenen UIViews. Dieses Bild funktioniert also, da der UIImageView bereits als Container während des Ladens des Storyboards (NIB) vorhanden ist und Sie erst später die interne Image-Eigenschaft festlegen.

Sie haben den Wert someValue für alle zukünftigen während des CellRenderings und der Ereignisbehandlung korrekt festgelegt. Wenn zum Beispiel ein @IBAction-Handler ausgeführt wird, nachdem die Zelle angezeigt und angetippt wurde, hat sie tatsächlich Zugriff auf someValue. Das ist, wo dein Testdruck gehen sollte. Was sind Sie schließlich mitsomeValue für?

Followup

So ist es ein einfacher Fehler; Sie müssen nur den Textwert in cellForRowAtIndexPath festlegen. Sie benötigen auch keine Kopie der Modelldaten in der Zelle (d. H. Sie müssen kein someValue-Feld in Ihrer Zelle haben). Konfigurieren Sie einfach die Benutzeroberfläche dynamisch von Ihren (richtig getrennt) Modelldaten:

statt:

cell.someValue = 5 

Sie gerade benötigen, zB:

cell.someValueLabel.text = "\(indexPath.row)" // or where ever you're getting your underlying model data from 

Es ist ein Irrglaube, init für alle zu verwenden, Dies. Die einzige Verantwortlichkeit von init für Tabellenzellen besteht darin, Speicher zuzuweisen. Eine Zelle ist ein vollständig dynamisches temporäres Objekt, und alle ihre Eigenschaften, die Anwendungsdaten widerspiegeln, müssen in der cellForRowAtIndexPath-Methode festgelegt werden. Das visuelle Rendering der Zelle wartet darauf, dass die Methode cellForRowAtIndexPath beendet wird. Es gibt also kein Timing-Problem.

+0

In der realen Version versuche ich, den 'indexPath.item' Wert zu übergeben, so dass ich einige machen kann geringfügige Änderungen am Aussehen der Zelle während der Initialisierung, basierend auf dem Inhalt, den sie anzeigt. – Nitroid

+0

Es ist ein Missverständnis, die Änderung während 'init' vorzunehmen. Die einzige Verantwortung von 'init' für Tabellenzellen ist die Zuweisung von Speicher. Eine Zelle ist ein vollständig dynamisches, temporäres Objekt, und alle ihre Eigenschaften, die die Anwendungsdaten widerspiegeln, müssen in der Methode 'cellForRowAtIndexPath' festgelegt werden. Das visuelle Rendering der Zelle wartet darauf, dass die 'cellForRowAtIndexPath'-Methode beendet wird. Es gibt also kein Timing-Problem. – BaseZen

0

Sie setzen den Wert von someValue, nachdem die Zelle initialisiert wurde.

Sie rufen während der Initialisierung print("Passed value is: \(someValue)") an.

Legen Sie einen Unterbrechungspunkt für die init-Methode Ihrer Zellklasse fest. Sie sollten es dort durchlaufen sehen, bevor Sie dieser Variablen den Wert 5 zuweisen.

1

Init-Methode wird aufgerufen, wenn die UICollectionView instanziiert wird.Sie protokollieren "someValue" in der init-Methode und es ist zu früh. Das Bild wird gerendert, da Sie direkt mit dem ImageView arbeiten, das bereits instanziiert wurde. Versuchen Sie, imageVIEW.Image in der init-Methode zu protokollieren, es sollte auch keine NULL sein (oder vielleicht nicht NULL, weil die Zelle wiederverwendet wird).

Sie sollten Ihre Arbeit in benutzerdefinierten Variablen Setter und Getters machen, wo Sie sicher sind, dass sie nicht Null sind.

var someValue: Int!{ 
    didSet { 
     print("Passed value is: \(newValue)") 
    } 
}