How to remove all items from an NSTableView managed by NSArrayController?

I use NSArrayController , NSMutableArray and NSTableView to show a list of my own custom objects (although this question probably applies if you just show a list of vanilla NSString objects).

At different points in time, I need to clear my array and update data from my data source. However, just calling removeAllObjects on my NSMutableArray does not cause a KVO update, so the list on the screen remains unchanged.

NSArrayController has a non- removeAllObjects method available that seems really weird. (It has addObject , which I use to add objects, ensuring that KVO is launched and the user interface is updated.)

The cleanest way that this succeeded is correct:

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

... so I somehow need to manually enter a KVO notification (this is in my test application class that contains the myArray property, which is NSMutableArray , as mentioned).

This seems wrong - is there a better way? From my googling, it seems that some people get confused due to the lack of removeAllObjects in NSArrayController , but have not seen better solutions.

I saw this solution:

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

but it looks even more unpleasant for me. At least my decision is at least slightly self-documenting.

Has Apple noticed that sometimes people may want to clear the list control through an NSArrayController ? This seems obvious, so I think I'm missing something ...

Also, of course, if I add new elements to the array (via NSArrayController ), this will cause KVO to be updated using NSArrayController/NSTableView , but:

  • Sometimes I don’t put any items on the list because they are not. So you just see old objects.
  • Anyway, it's a little yucky.
+7
cocoa macos nsarraycontroller
source share
5 answers

You do not remove items from the table view. It has no elements - it simply displays other objects of the object.

If you have connected an array of the array of the contents of the array with a binding to the array property of some other object, you should work with this property of this object. Use [[object mutableArrayValueForKey:@"property"] removeAllObjects] .

If, on the other hand, you have not linked the binding of the array to the contents of the array, you need to interact directly with its content . Use [[arrayController mutableArrayValueForKey:@"content"] removeAllObjects] . (You can also work with arrangedObjects instead of content . If someone doesn’t work, try another - I just did things the first way by binding the array controller to something else.)

+16
source share

If this problem had been solved like this:

 NSArrayController* persons = /* your array controller */; [[persons content] removeAllObjects]; 
+3
source share

Swift

 @IBOutlet var acLogs: NSArrayController! acLogs.removeObjects(acLogs.content as! [AnyObject]) 

worked for me.

+1
source share

Solution in Swift:

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

Just an update that works in Swift 4:

 let range = 0 ..< (self.arrayController.arrangedObjects as AnyObject).count self.arrayController.remove(atArrangedObjectIndexes: IndexSet(integersIn: range)) 
0
source share

All Articles