2009-03-14 6 views
7

Używam NSArrayController, i , aby wyświetlić listę własnych obiektów niestandardowych (chociaż to pytanie prawdopodobnie ma zastosowanie, jeśli wyświetlasz tylko listę obiektów z wanilią NSString).Jak usunąć wszystkie elementy z NSTableView kontrolowane przez NSArrayController?

W różnych momentach, potrzebuję wyczyścić moją tablicę i odświeżyć dane z mojego źródła danych. Jednak po prostu wywołanie removeAllObjects na moim obiekcie NSMutableArray nie powoduje aktualizacji KVO, więc lista na ekranie pozostaje niezmieniona.

NSArrayController ma noremoveAllObjects dostępna metoda, co wydaje się naprawdę dziwne. (To ma addObject, które używam, aby dodać obiekty, zapewniając KVO jest wyzwalany i interfejs użytkownika jest aktualizowany.)

najczystszy sposób udało mi się spowodować to zdarzyć właściwie jest:

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

... więc mam niby zrobić konieczności powiadomienia KVO ręcznie siebie (jest to w mojej klasie aplikacji testowej, która zawiera właściwość myArray, który jest NSMutableArray, jak wspomniano).

wydaje się źle - jest istnieje lepszy sposób? Z mojego googlowania wynika, że ​​kilka osób jest zdezorientowanych brakiem removeAllObjects w NSArrayController, ale nie widziałem żadnych lepszych rozwiązań.

Widziałem tego rozwiązania:

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

ale wygląda to jeszcze bardziej nieprzyjemne dla mnie. Przynajmniej moje rozwiązanie jest co najmniej marginalnie samo-dokumentujące.

Czy Apple nie zauważyło, że czasami ludzie mogą chcieć opróżnić kontrolkę listy zarządzaną przez obiekt NSArrayController? To wydaje się oczywiste, więc myślę, że muszę czegoś przegapić ...

Pomijając: oczywiście, jeśli dodam nowe elementy do tablicy (przez NSArrayController), to wyzwala aktualizację KVO z NSArrayController/NSTableView, ale :

  1. Czasami nie umieszczam żadnych pozycji na liście, ponieważ ich nie ma. Widzisz tylko stare przedmioty.
  2. W każdym razie to trochę brzydko.

Odpowiedz

16

Nie usuwa się przedmiotów z widoku tabeli. Nie ma żadnych przedmiotów - wyświetla tylko przedmioty innego przedmiotu.

Jeśli powiązanie powiązania tablicy treści kontrolera tablicowego z właściwością tablicy innego obiektu, powinieneś pracować z tą właściwością tego obiektu. Użyj [[object mutableArrayValueForKey:@"property"] removeAllObjects].

Jeśli, z drugiej strony, nie związałeś powiązania tablicy treści kontrolera tablicowego, musisz bezpośrednio skontaktować się z jego numerem content. Użyj [[arrayController mutableArrayValueForKey:@"content"] removeAllObjects]. (Możesz także pracować z arrangedObjects zamiast content. Jeśli nie działa, spróbuj innych - robiłem tylko rzeczy w pierwszy sposób, wiążąc kontroler tablicy z czymś innym.)

+0

Dzięki - to działa. Zmieniłem swój oryginalny kod w moim pytaniu na: [[self mutableArrayValueForKey: @ "myArray"] removeAllObjects]; i działa dobrze. Znacznie czystsze. Zapisałeś mutableArrayValueForKey w niewłaściwym miejscu - napraw to i zaznaczę to jako zaakceptowaną odpowiedź. :-) – Slacker

+3

Twoja metoda działa idealnie, gdy ArrayController jest ograniczony do tablicy. Ale nie działa, gdy ArrayController nie jest ograniczony do tablicy. Tablica 'content' pobierana z ArrayController jest' NSArray', a nie 'NSMutableArray'. Po prostu użyj metody z ArrayController, aby wyczyścić zawartość: 'NSRange range = NSMakeRange (0, [[anArrayController arrangedObjects] count]); [anArrayController removeObjectsAtArrangedObjectIndexes: [NSIndexSet indexSetWithIndexesInRange: range]];' – Quincy

+2

@Quincy '' 'NSRange'' 'rozwiązanie jest znacznie szybsze niż oryginalna odpowiedź lub' '' [anArrayController removeObjects: [anArrayController arrangedObjects]] '' '. Dzięki! – bdunagan

3

miał ten problem rozwiązać, jak również i to w ten sposób:

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

Niestety, to nie działa. Jeśli ktoś zadzwoni do [persons arranObjects], zawartość tablicy może nadal tam być. Po usunięciu wszystkich elementów z macierzy zawartości przy pomocy removeAllObjects, odkryłem, że musisz również wywołać [persons rearrangeObjects]. – ericg

+0

Program zawiesza się z tym ... – TCB13

0

rozwiązaniem w 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]) 

pracował dla mnie.