Domanda

Sfondo

Sto creando un Elenco sorgenti per la mia applicazione e lo voglio strutturato in modo simile a quello di iTunes, con due tipi di elementi:

  • " Fixed " articoli & # 8211; questi non cambiano e non possono essere spostati in & # 8211; in alto
  • Elementi modificabili sottostanti, che possono essere modificati dall'utente & # 8211; spostato, rinominato ecc. (nell'esempio di iTunes, come playlist e playlist smart)

Nella mia analogia di iTunes:

 iTunes Source List
(fonte: perspx.com )

Il modo in cui ho strutturato i miei dati finora è il seguente:

  • Gli elementi che voglio essere modificabili sono " gruppo " elementi, sotto forma di Group Entità di dati principali.
  • Ogni elemento nell'elenco Sorgente è rappresentato come un oggetto SourceListItem normale Objective-C in modo da poter associare ogni elemento a un titolo, un'icona, elementi figlio ecc.
  • Gli elementi fissi sono attualmente rappresentati dalle istanze SourceListItem , archiviate in un array nel mio oggetto controller.

La domanda

Non sono sicuro di come combinare questi due tipi di elementi nell'elenco Sorgente, in modo che gli elementi fissi siano nella parte superiore e sempre lì e non cambino, e gli elementi modificabili siano nella parte inferiore e possono essere spostati e modificato.

Queste sono le idee che mi sono venute finora:

  • Aggiungi gli elementi fissi al modello di dati di base. Ciò significa che posso creare un'entità per rappresentare gli elementi dell'elenco di origine e posizionare i miei elementi fissi e modificabili in questi casi. Quindi questi possono essere associati alla colonna della tabella Vista struttura con un controller di array / albero. Tuttavia, ciò significa che dovrei creare una nuova entità per rappresentare gli elementi dell'elenco di origine e quindi sincronizzare i Group con questo. Dovrei anche avere un modo per creare tutti gli elementi fissi una sola volta, e se accadesse qualcosa a uno dei file di archivio persistenti, gli elementi fissi non sarebbero visualizzati.

  • Unisci gli elementi fissi con gli elementi del gruppo. Mentre entrambi sono memorizzati in array separati, questo potrebbe essere fatto nel controller per la mia finestra quando la Vista struttura richiede i dati (se adottando il protocollo NSOutlineViewDataSource , non i bind). Tuttavia, ciò significa che dovrei creare nuovi SourceListItem per ciascun gruppo nel controller di array (per associare ciascuno con icone e altri attributi), archiviarli e quindi guardare il controller di array di gruppo per le modifiche a rimuovere, aggiungere o modificare le istanze SourceListItem quando vengono apportate modifiche ai gruppi.

Qualcuno ha idee migliori su come posso implementarlo?

Vorrei che la mia applicazione fosse compatibile con OS X v10.5, quindi preferirei qualsiasi soluzione che non dipendesse dall'installazione di Snow Leopard.

È stato utile?

Soluzione

Sto lavorando a un'app che ha esattamente lo stesso comportamento, ed ecco come lo sto facendo:

Ho 5 entità principali nel mio modello di dati di base:

  1. AbstractItem - un'entità astratta che ha gli attributi comuni a tutti gli elementi, come name , peso e modificabili . Ha anche due relazioni: parent (relazione one-to con AbstractItem ) e children (relazione to-many con AbstractItem e l'inverso di parent ).
  2. Group - Entità figlio concreta di AbstractItem .
  3. Cartella - Entità figlio concreta di AbstractItem . Aggiunge una relazione molti-a-molti all'entità Item di base.
  4. SmartFolder - Entità figlio concreta di Cartella . Aggiunge un attributo binario predicateData . Sostituisce gli articoli di Folder " accedente alla relazione per restituire i risultati dell'esecuzione di una richiesta di recupero con il predicato definito dall'attributo predicateData .
  5. DefaultFolder - Entità figlio concreta di SmartFolder . Aggiunge un attributo stringa identificatore .

Per la " Library " elementi della sezione, inserisco oggetti DefaultFolder e offro loro un identificatore univoco in modo che io possa recuperarli facilmente e differenziarli. Offro anche loro un NSPredicate che corrisponde a quali elementi dovrebbero mostrare. Ad esempio, il " Music " DefaultFolder avrebbe un predicato per recuperare tutti gli elementi musicali, i "Podcast" DefaultFolder avrebbe un predicato per recuperare tutti gli elementi Podcast, ecc.

Gli elementi a livello di radice (" Library " ;, " Shared " ;, " Store " ;, " Genius " ;, etc) sono tutti elementi Group con un nil genitore. I gruppi e le cartelle che non possono essere modificati hanno l'attributo modificabile impostato su NO .

Per quanto riguarda effettivamente ottenere queste cose nel tuo outlineView, dovrai implementare tu stesso i protocolli NSOutlineViewDataSource e NSOutlineViewDelegate . C'è troppa complessità comportamentale qui per pomparla attraverso un NSTreeController . Tuttavia, nella mia app, ho ottenuto tutto il comportamento (anche il trascinamento della selezione) in meno di 200 righe di codice (quindi non è così cattivo).

Altri suggerimenti

Non iniettare sciocchezze nel tuo set di dati semplicemente per supportare una vista. Questo non solo va contro il modello di progettazione MVC, ma aggiunge inutili complessità (cioè "più potenziale per i bug") alla parte più importante: la gestione dei dati degli utenti.

Detto questo, l'utilizzo di Bindings in questo particolare scenario è ciò che sta causando così tanto attrito. Perché non rifuggire del tutto dagli attacchi? Sei sulla buona strada, penso, usando il protocollo NSOutlineViewDataSource, ma non sei andato abbastanza lontano. Invece, affidati pienamente a questo protocollo (ancora perfettamente valido e in qualche modo superiore).

Dovresti scambiare essenzialmente la facilità di installazione (e la facilità di notifica delle modifiche) per il pieno controllo sulla struttura ad albero.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top