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.

È stato utile?

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)
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top