2009-03-14 10 views
7

J'utilise un NSArrayController, NSMutableArray et NSTableView pour afficher une liste de mes propres objets personnalisés (bien que cette question s'applique probablement si vous montrez juste une liste d'objets vanillés NSString aussi).Comment supprimer tous les éléments d'un NSTableView contrôlé par NSArrayController?

À divers moments, j'ai besoin d'effacer mon tableau et rafraîchir les données de ma source de données. Cependant, le simple fait d'appeler removeAllObjects sur mon objet NSMutableArray ne déclenche pas les mises à jour KVO, donc la liste à l'écran reste inchangée.

NSArrayController a aucuneremoveAllObjects méthode disponible, ce qui semble vraiment bizarre. (Il ne addObject, que j'utilise pour ajouter les objets, en assurant la KVO est déclenchée et l'interface utilisateur est mis à jour.)

La façon la plus propre que j'ai réussi à faire cela se produire correctement est:

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

... donc je suis un peu d'avoir à faire la notification KVO moi-même manuellement (ce qui est dans mon test classe app, qui contient la propriété myArray, qui est NSMutableArray, comme mentionné.)

cela semble mal - est il y a une meilleure façon? De mon googling, il semble que quelques personnes sont confus par le manque de removeAllObjects en NSArrayController, mais n'ont pas vu de meilleures solutions.

J'ai vu cette solution:

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

mais cela semble encore plus désagréable pour moi. Au moins, ma solution est au moins marginalement auto-documentée.

Apple n'a-t-il pas remarqué que les utilisateurs souhaitaient parfois vider un contrôle de liste géré via un objet NSArrayController? A part: bien sûr, si j'ajoute de nouveaux éléments à la matrice (via NSArrayController), cela déclenche une mise à jour de KVO avec le NSArrayController/NSTableView, mais :

  1. Parfois, je ne mets aucun élément dans la liste, car il n'y en a aucun. Donc, vous ne voyez que les anciens éléments.
  2. C'est un peu dégueulasse quand même.

Répondre

16

Vous ne supprimez pas les éléments d'une vue de table. Il n'a aucun élément - il affiche simplement les éléments d'un autre objet.

Si vous avez lié la liaison de tableau de contenu du contrôleur RAID à une propriété de tableau d'un autre objet, vous devez utiliser la propriété de cet objet. Utilisez [[object mutableArrayValueForKey:@"property"] removeAllObjects].

Si, en revanche, vous n'avez pas lié la liaison de tableau de contenu du contrôleur RAID, vous devez interagir directement avec son content. Utilisez [[arrayController mutableArrayValueForKey:@"content"] removeAllObjects]. (Vous pouvez aussi travailler avec au lieu de content) Si l'un ne fonctionne pas, essayez l'autre - j'ai seulement fait les choses de la première façon, en liant le contrôleur RAID à autre chose.)

+0

Merci - cela fonctionne. J'ai changé mon code original dans ma question: [[self mutableArrayValueForKey: @ "myArray"] removeAllObjects]; et cela fonctionne bien. Beaucoup plus propre. Vous avez orthographié mutableArrayValueForKey incorrect BTW - corriger cela et je vais le marquer comme la réponse acceptée. :-) – Slacker

+3

Votre méthode fonctionne parfaitement lorsque ArrayController est lié à un tableau. Mais cela ne fonctionne pas lorsque ArrayController n'est pas lié à un tableau. Le tableau 'content' que vous obtenez à partir de ArrayController est un' NSArray' et non 'NSMutableArray'. Utilisez simplement la méthode de ArrayController pour effacer le contenu: 'NSRange range = NSMakeRange (0, [[anArrayController arrangedObjects] count]); [unArrayController removeObjectsAtArrangedObjectIndexes: [NSIndexSet indexSetWithIndexesInRange: plage]];' – Quincy

+2

@Quincy Le '' 'NSRange'' 'la solution est significativement plus rapide que la réponse d'origine ou' '' ['anArrayController removeObjects: [unArrayController arrangedObjects]]' ''. Merci! – bdunagan

3

eu ce problème aussi bien et a résolu le problème de cette façon:

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

Malheureusement, cela ne fonctionne pas. Si l'on appelait [personsObjects], le contenu du tableau pourrait toujours être présent. Après avoir supprimé tous les éléments du tableau de contenu avec removeAllObjects, j'ai trouvé que vous deviez aussi appeler [persons rearrangeObjects]. – ericg

+0

mon programme se bloque avec cette ... – TCB13

0

Solution à 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]) 

a fonctionné pour moi.

Questions connexes