hinzufügen KVO zu UITableViewCell
Habe ich eine custom UITableViewCell die Anzeige von verschiedenen Attribute einer Person Objekt (unterstützt von Core Data) ... einige Beschriftungen, Bilder etc. Ich habe derzeit zwingen, die gesamte tableview neu laden, wenn keine änderungen der Eigenschaft, und das ist offensichtlich nicht effizient. Ich weiß, mit KVO, ich sollte in der Lage sein, einen listener hinzufügen, um eine Beschriftung in die Zelle, das Zuhören kann für änderungen in der Person dessen Eigenschaften. Aber ich bin mir nicht sicher, wie es zu implementieren, und finde keine Beispiele.
Hier ist, was ich normalerweise tun, in meinem UITableView ist cellForRowAtIndexPath:
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath
{
static NSString *simple = @"CustomCellId";
CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:simple];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
for (id findCell in nib )
{
if ( [findCell isKindOfClass: [CustomCell class]])
{
cell = findCell;
}
}
}
Person *managedObject = [self.someArray objectAtIndex: indexPath.row];
cell.namelabel.text = managedObject.displayName;
return cell;
}
Der Zelle verknüpft ist, die in IB. Ich würde mir wünschen, zu erkennen, wenn displayName änderungen, und aktualisieren der Beschriftung name.
Dank
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hintergrund -, möchten Sie wahrscheinlich Lesen die Key-Value-Observing und Key-Value-Coding-Guides, wenn Sie nicht bereits getan haben. Überprüfen Sie dann die NSKeyValueObserving Kategorie Methoden.
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html
Kurz gesagt, müssen Sie sorgfältig verwalten das hinzufügen und entfernen von dem Objekt der Beobachtung auf die beobachteten Objekte Liste der Beobachter (verzeihen Sie das scheinbare Redundanz von dieser Aussage). Sie wollen nicht zu haben, ein Objekt Weg gehen Beobachter noch registriert, oder Sie bekommen Beschwerden und mögliche andere Probleme.
Das heißt, Sie verwenden
-addObserver:keyPath:options:context
um ein Objekt als Beobachter. Kontext sollten eine statisch deklarierten string. Das argument der Optionen steuert, welche Daten Sie wieder in Ihre Beobachtung-Methode (siehe unten). Der Schlüsselpfad ist der Pfad der property-Namen von dem beobachteten Objekt zu der beobachteten Eigenschaft (dies kann Durchlaufen mehrere Objekte, und werden aktualisiert, wenn intermediate-Objekte ändern, nicht nur, wenn der Blatt-Eigenschaft ändert).In Ihrem Fall, Sie konnten beobachten, das label und verwenden Sie die
text
Schlüsselpfad, oder die Zelle, und verwenden Sie dienameLabel.text
Schlüssel Weg. Wenn die Tabelle view-Klasse waren sehr unterschiedlich gestaltet, könnten Sie beobachten das gesamte array von Zellen, aber es gibt keine solche Eigenschaft auf UITableView. Das problem mit die Zelle zu beobachten ist, dass die Tabelle Ansicht könnte diese jederzeit wieder löschen (wenn Ihr design nutzt mehrere Zellen, die dem gleichen Zweck dienen, in einer Liste mit variabler Länge). Wenn Sie wissen, Ihre Zellen sind statisch, Sie können wahrscheinlich beobachten, ohne Sie zu kümmern.Sobald Sie ein Beobachter registriert, dass die observer implementieren müssen
-observeValueForKeyPath:ofObject:change:context:
bestätigen Sie, dass die Kontext-matches (man Vergleiche nur die Zeiger-Wert, um Ihre static string Adresse; andernfalls aufrufen, super Umsetzung), dann schau mal in die change-Wörterbuch für die Daten, die Sie wollen (oder Fragen Sie einfach das Objekt für Sie direkt) und es verwenden, um aktualisieren Sie Ihr Modell, wie Sie sehen, passen.Gibt es viele Beispiele von KVO in Beispiel-code, einschließlich der auf der Apple-developer-Website, und als Teil der Bindungen Proben auf Malcolm Crawford (mmalc)'s site, aber das meiste ist für Mac OS X, nicht iOS.
text
.cell
sollte beobachtet werden, aber diePerson
Objekt! Da das Objekt ändern kann, und die Zelle reagieren soll!Die obige Antwort ist großartig für die statischen Zellen. Mit KVO für
UITableViewCell
s noch funktioniert mit der Zelle wiederverwenden. Fügen Sie die Beobachter, die Sie brauchen, wenn die Zelle angezeigt wird, und entfernen Sie Sie, wenn die Zelle nicht mehr angezeigt. Der einzige trick ist, dass Apple scheint nicht zu senden didEndDisplayingCell:, so Beobachter entfernt werden müssen, werden an zwei Orten auf iOS 6.1Kann Folgendes auftreten, wenn der Beobachter nicht aufgeräumt. Der Beobachter kann versuchen, Sie zu Benachrichtigen, was auch immer Objekt, die Position im Speicher, die möglicherweise gar nicht existieren.
<NSKeyValueObservationInfo 0x1d6e4860> (
<NSKeyValueObservance 0x1d4ea9f0: Observer: 0x1d6c9540, Key path: someKeyPath, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x1c5c7e60>
<NSKeyValueObservance 0x1d1bff10: Observer: 0x1d6c9540, Key path: someOtherKeyPath, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x1c588290>)
Dies funktioniert:
In configureCell:
In CustomCell:
In meinem Fall fügte ich ein Beobachter, um die benutzerdefinierte Zelle label forKeyPath "text" mit den Optionen (
NSKeyValueObservingOptionNew
|NSKeyValueObservingOptionOld
).Beim beobachten der Wert für die Schlüsselpfad ich überprüfen, um sicherzustellen, Schlüsselpfad, den ich will, nur als eine zusätzliche Maßnahme und dann rufe ich meine Methode für was auch immer die operation, die ich durchführen wollen, auf, dass das label
e.g in meinem Fall
Bevorzuge ich eine Lösung, in der die
UITableViewCell
hat alle von der KVO auf seine eigenen. Mein setup ist wie folgt:In meiner Zelle Unterklasse, ich habe eine Eigenschaft, die immer einen starken Bezug zu meiner model-Klasse, von dem ich wieder an meine Daten, und eine Methode, die ich anrufen, wenn ich will bringen Sie ein neues Objekt der Eigenschaft:
Umsetzung:
Beachten Sie, dass die tatsächliche KVO behandelt wird auf einem hintergrund-thread zu vermeiden, die Blockierung der Haupt-thread während des Blätterns. Beachten Sie auch, dass
-populateFromObject:
sofort zurückkehrt und deshalb anzeigen würde, eine unbewohnte Zelle. Um dies zu vermeiden, wir verstecken die den Inhalt anzeigen, bis die Zelle vollständig gefüllt ist.Jetzt das einzige, was noch zu implementieren ist eine Methode der Klasse auf
YourModelObject
gibt ein array mit den Schlüsseln, die Sie wollen KVO:..und in
UITableViewController
:Die starke Referenz von der Zelle auf das Modell-Objekt stellt sicher, dass das Objekt nicht bekommen freigegeben, während die Zelle noch beobachtet eine seiner Eigenschaften, d.h. sichtbar ist. Wenn die Zelle freigegeben wird, das KVO ist nicht registriert und erst dann das Modell-Objekt wäre aufgehoben. Für die Bequemlichkeit ich habe auch einen schwachen Verweis aus dem Modell-Objekt zurück, das die Zelle die in handliches kommen kann, wenn die Umsetzung
UITableView
delegate-Methoden.