2009-03-14 5 views
7

Ich verwende eine NSArrayController, NSMutableArray und NSTableView, um eine Liste meiner eigenen benutzerdefinierten Objekte anzuzeigen (obwohl diese Frage wahrscheinlich gilt, wenn Sie nur eine Liste von NSString-Objekten auch anzeigen).Wie sollte ich alle Elemente aus einem NSTableView entfernen, das von NSArrayController gesteuert wird?

Zu verschiedenen Zeitpunkten muss ich mein Array löschen und die Daten aus meiner Datenquelle aktualisieren. Der Aufruf von removeAllObjects auf meinem Objekt NSMutableArray löst jedoch nicht die KVO-Aktualisierungen aus, sodass die Liste auf dem Bildschirm unverändert bleibt.

NSArrayController hat keineremoveAllObjects Methode zur Verfügung, die wirklich seltsam scheint. (Es tut addObject, die ich verwenden, um die Objekte hinzufügen, die KVO sicherzustellen ausgelöst wird und die Benutzeroberfläche aktualisiert wird.)

Der sauberste Weg, ich habe es geschafft, dies ist geschehen, um zu bewirken, richtig:

[self willChangeValueForKey:@"myArray"]; 
[myArray removeAllObjects]; 
[self didChangeValueForKey:@"myArray"]; 

... so bin ich irgendwie die KVO Benachrichtigung manuell selbst zu tun haben (in meinem Test-App-Klasse ist, dass enthält die myArray Eigenschaft, die NSMutableArray ist, wie erwähnt.)

Dies scheint falsch - ist gibt es einen besseren Weg? Von meinem googeln scheint es, dass ein paar Leute durch das Fehlen von removeAllObjects in NSArrayController verwirrt sind, aber keine besseren Lösungen gesehen haben.

Ich habe diese Lösung gesehen:

[self removeObjectsAtArrangedObjectIndexes: 
    [NSIndexSet indexSetWithIndexesInRange: 
    NSMakeRange(0, [[self arrangedObjects] count])]]; 

aber das sieht noch unangenehmer zu mir. Zumindest ist meine Lösung zumindest marginal selbstdokumentierend.

Hat Apple nicht bemerkt, dass Benutzer manchmal ein Listensteuerelement leeren möchten, das über ein Objekt NSArrayController verwaltet wird? Das scheint irgendwie offensichtlich zu sein, also denke ich, dass ich etwas vermissen muss ...

Beiseite: natürlich, wenn ich neue Elemente zum Array hinzufügen (über NSArrayController), dann löst dies ein KVO-Update mit der NSArrayController/NSTableView, aber :

  1. Manchmal lege ich keine Elemente in die Liste, weil es keine gibt. Du siehst also nur die alten Gegenstände.
  2. Das ist ein bisschen eklig sowieso.

Antwort

16

Sie entfernen keine Elemente aus einer Tabellenansicht. Es hat keine Gegenstände - es zeigt nur die Gegenstände eines anderen Gegenstandes an.

Wenn Sie die Content-Array-Bindung des Array-Controllers an eine Array-Eigenschaft eines anderen Objekts binden, sollten Sie mit dieser Eigenschaft dieses Objekts arbeiten. Verwenden Sie [[object mutableArrayValueForKey:@"property"] removeAllObjects].

Wenn Sie andererseits die Array-Bindung des Array-Controllers nicht gebunden haben, müssen Sie direkt mit dessen content interagieren. Verwenden Sie [[arrayController mutableArrayValueForKey:@"content"] removeAllObjects]. (Sie könnten auch mit arrangedObjects anstelle von content arbeiten. Wenn einer nicht funktioniert, versuchen Sie den anderen - ich habe die Dinge nur auf die erste Art gemacht, den Array-Controller an etwas anderes gebunden.)

+0

Danke - das funktioniert. Ich habe meinen ursprünglichen Code in meiner Frage geändert in: [[self mutableArrayValueForKey: @ "myArray"] removeAllObjects]; und es funktioniert gut. Viel sauberer. Sie buchstabiert mutableArrayValueForKey falsch btw - fix das und ich werde es als die akzeptierte Antwort markieren. :-) – Slacker

+3

Ihre Methode funktioniert einwandfrei, wenn der ArrayController an ein Array gebunden ist. Aber es funktioniert nicht, wenn der ArrayController nicht an ein Array gebunden ist. Das 'content'-Array, das Sie vom ArrayController erhalten, ist ein 'NSArray', nicht' NSMutableArray'. Verwenden Sie einfach die Methode from ArrayController, um den Inhalt zu löschen: 'NSRange range = NSMakeRange (0, [[anArrayController arearchedObjects] count]); [anArrayController removeObjectsAtArrangedObjectIndexes: [NSIndexSet indexSetWithIndexesInRange: range]];' – Quincy

+2

@Quincy Die '' 'NSRange'' 'Lösung ist deutlich schneller als die ursprüngliche Antwort oder' '[anArrayController removeObjects: [anArrayController arrangedObjects]]' ''. Vielen Dank! – bdunagan

3

dieses Problem auch hatten und es auf diese Weise gelöst:

NSArrayController* persons = /* your array controller */; 
[[persons content] removeAllObjects]; 
+1

Leider funktioniert das nicht. Wenn man [persons arrangedObjects] aufrufen würde, könnte der Inhalt des Arrays noch vorhanden sein. Nach dem Entfernen aller Elemente aus dem Inhalts-Array mit removeAllObjects habe ich festgestellt, dass Sie auch [persons rearageObjects] aufrufen müssen. – ericg

+0

mein Programm stürzt mit diesem ... ab – TCB13

0

Lösung in Swift:

if let ac = arrayController 
{ 
    let range:NSRange = NSMakeRange(0, ac.arrangedObjects.count); 
    let indexSet:NSIndexSet = NSIndexSet(indexesInRange: range); 
    ac.removeObjectsAtArrangedObjectIndexes(indexSet); 
} 
1

Swift

@IBOutlet var acLogs: NSArrayController! 

acLogs.removeObjects(acLogs.content as! [AnyObject]) 

für mich gearbeitet.

Verwandte Themen