NSTreeControllerを使用せずにNSOutlineViewで項目を選択するにはどうすればよいですか?
-
11-09-2019 - |
質問
使っています NSOutlineView
それなし NSTreeController
そして独自のデータソースを実装しました。アイテムを選択する最良の方法は何ですか?NSOutlineView
すでにサポートしています expandItem:
そして collapseItem:
. 。そして、`selectItem: のような便利なメソッドがありません。どうすればプログラム的に実行できますか?
ありがとう。
解決
何かが見つからない場合は、忘れずにスーパークラスを参照してください。この場合、必要なメソッドの 1 つは、NSOutlineView の直接のスーパークラスである NSTableView からのものです。
解決策は、 を使用して項目の行インデックスを取得します rowForItem:
, -1 でない場合 (アイテムが表示されない/見つからない)、 それを使用してインデックスセットを作成します [NSIndexSet indexSetWithIndex:]
そしてそのインデックスセットを次のように渡します の selectRowIndexes:byExtendingSelection:
方法.
他のヒント
ここで私は最終的に終わった方法です。提案や修正は常に歓迎しております。
@implementation NSOutlineView (Additions)
- (void)expandParentsOfItem:(id)item {
while (item != nil) {
id parent = [self parentForItem: item];
if (![self isExpandable: parent])
break;
if (![self isItemExpanded: parent])
[self expandItem: parent];
item = parent;
}
}
- (void)selectItem:(id)item {
NSInteger itemIndex = [self rowForItem:item];
if (itemIndex < 0) {
[self expandParentsOfItem: item];
itemIndex = [self rowForItem:item];
if (itemIndex < 0)
return;
}
[self selectRowIndexes: [NSIndexSet indexSetWithIndex: itemIndex] byExtendingSelection: NO];
}
@end
いいえ、selectItem:
の方法はないが、rowForItem:
方法があります。あなたは上記のselectRowIndexes:byExtendingSelection:
の使用についてのピーターのアドバイスをすることを組み合わせた場合、あなたはあなたが必要なすべての情報を持っている必要があります。
あなたは本当に私が一貫性のために呼び出すsetSelectedItem:
をお勧めします項目を選択する方法を持っていると思った場合、あなたはNSOutlineView
上のカテゴリでこのような何かを書くことができます。
- (void)setSelectedItem:(id)item {
NSInteger itemIndex = [self rowForItem:item];
if (itemIndex < 0) {
// You need to decide what happens if the item doesn't exist
return;
}
[self selectRowIndexes:[NSIndexSet indexSetWithIndex:itemIndex] byExtendingSelection:NO];
}
このコードは実際に動作する場合は、私は考えています。私はちょうど概念を説明するために、それを書き上げます。
ここでは、プログラムPXSourceListの項目を選択するために使用されるコードスニペットです。
sourceListのは、通常のPXSouceListオブジェクトであると私は、アウトラインの最初のグループに2つ目の項目を選択したかっます。
あなたがまだ知らない場合は、iTunesの/メールスタイルのアウトラインを探して再場合は、NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]]; [sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];
、PXSourceListはNSOutlineViewための優れた代替品です。ここでそれを拾います。 PxSourceListする
この古い質問ですが、状況は同じです。迅速なバージョンの要求があったように、ここで私の感想です。私はあなたではなくNSOutlineViewを拡張するよりも、自分のデータソースクラスと直接対話すべきだと思うように私は私のために動作するように受け入れられて答えを見つけることができませんでした。それらが展開されていない限りうるさく、アウトラインはそれはあなたのデータソースを使用するように簡単です理由である行を見つけることができません。私の場合、私はあなたがトップレベルで開始し、あなたが拡大しようとしている実際の項目に向けて、あなたのように動作するように、親の逆の順序であなたのアイテムを展開する必要があることがわかりました。私は、内蔵されるべきであるように感じるが、私は何かを逃した場合を除き - そうではありません。
。この例ではFileItemは、私のデータソースのコレクションアイテムクラスです。それが表示された階層の一部である場合に有効にする必要があるプロパティ「親」が含まれています。
func selectItem(_ item: FileItem, byExtendingSelection: Bool = false) {
guard let outlineView = outlineView else { return }
var itemIndex: Int = outlineView.row(forItem: item)
if itemIndex < 0 {
var parent: FileItem? = item
var parents = [FileItem?]()
while parent != nil {
parents.append(parent)
parent = parent?.parent
}
let reversedTree = parents.compactMap({$0}).reversed()
for level in reversedTree {
outlineView.expandItem(level, expandChildren: false)
}
itemIndex = outlineView.row(forItem: item)
if itemIndex < 0 {
print("Didn't find", item)
return
}
}
print("Expanding row", itemIndex)
outlineView.selectRowIndexes(IndexSet(integer: itemIndex), byExtendingSelection: byExtendingSelection)
outlineView.scrollRowToVisible(itemIndex)
}