Come selezionare gli elementi in NSOutlineView senza NSTreeController?
-
11-09-2019 - |
Domanda
sto usando NSOutlineView
senza NSTreeController
e hanno messo in atto la mia origine dati. Qual è il modo migliore per selezionare una voce?
Supporto NSOutlineView
già expandItem:
e collapseItem:
. E mi manca un metodo pratico come `selectItem :. Come posso farlo programatically?
Grazie.
Soluzione
Ricordati di guardare in superclassi quando non si riesce a trovare qualcosa. In questo caso, uno dei metodi necessari viene da NSTableView, che è immediata superclasse di NSOutlineView.
La soluzione è quella di ottenere l'indice di riga per l'oggetto utilizzando rowForItem:
, e se non è -1 (voce non visibile / non trovato), creare un indice impostato con con [NSIndexSet indexSetWithIndex:]
e passare tale indice impostato il metodo selectRowIndexes:byExtendingSelection:
Altri suggerimenti
Ecco come ho finalmente finito. Suggerimenti e correzioni sono sempre i benvenuti.
@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
No, non c'è un metodo selectItem:
, ma c'è un metodo rowForItem:
. Se si combinano con il consiglio di Peter sull'utilizzo selectRowIndexes:byExtendingSelection:
sopra, si dovrebbe avere tutte le informazioni necessarie.
Se davvero voleva avere un metodo per selezionare una voce, che mi sento di raccomandare setSelectedItem:
chiamando per amore di coerenza, si potrebbe scrivere qualcosa di simile in una categoria a 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];
}
Non ho idea se questo codice funziona in realtà; Ho appena precipitai fuori per illustrare il concetto.
Ecco un frammento di codice che ho usato per selezionare a livello di codice un elemento in un PXSourceList.
listaOrigine è un oggetto PXSouceList regolare e ho voluto selezionare la seconda voce nel primo gruppo del contorno.
NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]]; [sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];
Se non si conosce ancora, PXSourceList è un ottimo sostituto per un NSOutlineView se si è alla ricerca di itunes stile / mail contorni. Raccoglierlo qui: PxSourceList
Questa è una vecchia questione, ma la situazione è ancora la stessa. Come c'era una richiesta per una versione veloce, ecco il mio introito. Non ho trovato la risposta accettata a lavorare per me, come penso che si dovrebbe interagire direttamente con la classe di origine di dati piuttosto che estendere il NSOutlineView. Terribilmente, il contorno non troverà le righe a meno che non si espandono, che è il motivo per cui è più semplice utilizzare il dataSource. Nel mio caso ho scoperto che è necessario ampliare il genitore del degli elementi in ordine inverso, in modo che si avvia al livello più alto e il tuo lavoro verso l'elemento reale si sta cercando di espandersi. Mi sento come che dovrebbe essere costruito in, ma se non ho perso qualcosa - non è
.In questo esempio FileItem è la mia fonte di dati di classe voce della raccolta. Esso contiene una proprietà "padre" che deve essere valido se è parte della gerarchia visualizzata.
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)
}