Pergunta

Eu estou usando NSOutlineView sem NSTreeController e implementaram a minha própria fonte de dados. Qual é a melhor maneira de selecionar um item? apoio NSOutlineViewexpandItem: e collapseItem:. E eu estou sentindo falta de um método prático como `selectItem :. Como posso fazê-lo através de programação?

Obrigado.

Foi útil?

Solução

Lembre-se de olhar em superclasses quando você não consegue encontrar algo. Neste caso, um dos métodos que você precisa vem de NSTableView, que é superclasse imediata da NSOutlineView.

A solução é obter o índice da linha para o item usando rowForItem: , e se não for -1 (item não visível / não encontrado), criar um conjunto de índices com ele com [NSIndexSet indexSetWithIndex:] e passar esse conjunto de índice para o método selectRowIndexes:byExtendingSelection:

Outras dicas

Aqui está como eu, finalmente, acabou. Sugestões e correções são sempre bem-vindos.

@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

Não, não é um método selectItem:, mas existe um método rowForItem:. Se você combinar isso com o conselho de Peter sobre o uso selectRowIndexes:byExtendingSelection: acima, você deve ter todas as informações que você precisa.

Se você realmente queria ter um método para selecionar um item, que eu recomendaria setSelectedItem: pedindo uma questão de coerência, você poderia escrever algo como isto em uma categoria em 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];
}

Eu não tenho idéia se este código realmente funciona; Eu apenas correu-lo para ilustrar o conceito.

Aqui está um trecho de código que eu usei para programaticamente selecionar um item em uma PXSourceList.

ListaDeOrigem é um objeto PXSouceList regular e eu queria para selecionar o segundo item no primeiro grupo do contorno.

    NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]];
    [sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];

Se você não sabe ainda, PXSourceList é um excelente substituto para um NSOutlineView se você está procurando contornos itunes / estilo mail. Buscá-lo aqui: PxSourceList

Esta é uma questão de idade, mas a situação ainda é o mesmo. Como não havia um pedido de uma versão rápida, aqui é a minha opinião. I não encontrou a resposta aceita trabalhar para mim como eu acho que você deve interagir diretamente com sua classe de origem de dados em vez de estender a NSOutlineView. Irritantemente, o esboço não vai encontrar linhas a menos que eles são expandidos que é por isso que é mais simples de usar sua fonte de dados. No meu caso, descobri que você tem que expandir o pai é de seus itens na ordem inversa, de modo que você comece no nível superior e trabalhar seu caminho para o item real que você está tentando expandir. Eu me sinto como que deve ser construído em, mas a menos que eu perdi alguma coisa - não é

.

Neste exemplo FileItem é minha classe item de coleção fonte de dados. Ele contém uma propriedade "pai" que precisa ser válida se for parte da hierarquia exibida.

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)
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top