NSArrayControllerによって制御されるNSTableViewからすべてのアイテムを削除するにはどうすればよいですか?
-
22-07-2019 - |
質問
私は NSArrayController
、 NSMutableArray
および NSTableView
を使用して、独自のカスタムオブジェクトのリストを表示しています(ただし、この質問はおそらくバニラ NSString
オブジェクトのリストも表示されているだけです。)
さまざまな時点で、配列をクリアし、データソースからデータを更新する必要があります。ただし、 NSMutableArray
オブジェクトで removeAllObjects
を呼び出しても、KVOの更新はトリガーされないため、画面上のリストは変更されません。
NSArrayController
には no removeAllObjects
メソッドがありますが、これは本当に奇妙に思えます。 (これには addObject
があり、これを使用してオブジェクトを追加し、KVOがトリガーされ、UIが更新されるようにします。)
これを正しく発生させた最もクリーンな方法は次のとおりです。
[self willChangeValueForKey:@"myArray"];
[myArray removeAllObjects];
[self didChangeValueForKey:@"myArray"];
...だから私は自分で手動でKVO通知を行う必要があります(これは myArray
プロパティを含む私のテストアプリクラスにあります、それは NSMutableArray
、前述のとおり。)
これは間違っているようです-より良い方法はありますか?私のグーグルからは、 NSArrayController
に removeAllObjects
がないことで混乱している人もいるようですが、より良い解決策は見当たりません。
この解決策を見ました:
[self removeObjectsAtArrangedObjectIndexes:
[NSIndexSet indexSetWithIndexesInRange:
NSMakeRange(0, [[self arrangedObjects] count])]];
しかし、これは私にとってさらに不快に見えます。少なくとも私の解決策は、少なくともわずかな自己文書化です。
Appleは、 NSArrayController
オブジェクトを介して管理されているリストコントロールを空にしたい場合があることに気づきませんでしたか?これは一種の明白なように思えるので、私は何かを見逃しているに違いないと思う...
脇:もちろん、( NSArrayController
を介して)配列に新しいアイテムを追加すると、 NSArrayController / NSTableView
でKVO更新がトリガーされますが、
- リストに項目がないので、リストに項目を入れないこともあります。したがって、古いアイテムだけが表示されます。
- これはとにかく少し不愉快です。
解決
テーブルビューからアイテムを削除しないでください。アイテムはありません。別のオブジェクトのアイテムを表示するだけです。
配列コントローラーのコンテンツ配列バインディングを他のオブジェクトの配列プロパティにバインドした場合、そのオブジェクトのそのプロパティを操作する必要があります。 [[object mutableArrayValueForKey:@" property"] removeAllObjects]
を使用します。
content
と直接やり取りする必要があります。 [[arrayController mutableArrayValueForKey:@" content"] removeAllObjects]
を使用します。 ( content
の代わりに arrangedObjects
を使用することもできます。一方が機能しない場合は、もう一方を試してください。コントローラーを他のものに接続します。) 他のヒント
この問題も同様に解決し、次のように解決しました:
NSArrayController* persons = /* your array controller */;
[[persons content] removeAllObjects];
Swift
@IBOutlet var acLogs: NSArrayController!
acLogs.removeObjects(acLogs.content as! [AnyObject])
私のために働いた。
Swiftのソリューション:
if let ac = arrayController
{
let range:NSRange = NSMakeRange(0, ac.arrangedObjects.count);
let indexSet:NSIndexSet = NSIndexSet(indexesInRange: range);
ac.removeObjectsAtArrangedObjectIndexes(indexSet);
}
Swift 4で機能するアップデート
let range = 0 ..< (self.arrayController.arrangedObjects as AnyObject).count
self.arrayController.remove(atArrangedObjectIndexes: IndexSet(integersIn: range))