NSTreeControllerを使用せずにNSOutlineViewで項目を選択するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1096768

  •  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つ目の項目を選択したかっます。

    NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]];
    [sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];
あなたがまだ知らない場合は、iTunesの/メールスタイルのアウトラインを探して再場合は、

、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)
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top