Como selecionar itens na NSOutlineView sem NSTreeController?
-
11-09-2019 - |
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 NSOutlineView
já expandItem:
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.
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)
}