Domanda

Apple ha un piccolo tutorial per creare una semplice interfaccia master-dettaglio. Interface Builder ne genererà anche automaticamente uno per te da un'entità Core Data. Tuttavia, sto cercando di fare qualcosa di più complicato del semplice esempio e ho lottato per un po 'per farlo funzionare.

Ho un'applicazione basata su documenti Core Data. Il modello include un'entità astratta Pagina e diverse sottogruppi concreti di Pagina. Tutte le pagine hanno alcuni attributi in comune (come "nome") e quelli sono definiti in Pagina. Ovviamente, le entità secondarie hanno gli attributi che sono unici per loro.

Voglio che l'interfaccia consenta all'utente di vedere tutti i tipi di pagine nell'elenco principale (un NSTableView). Quando selezionano una Pagina, i campi di dettaglio visualizzati dipendono dal tipo di Pagina.

Ecco cosa ho adesso:

Ho un file pennino principale, in cui viene visualizzato l'elenco principale, oltre a tutti i campi comuni a una Pagina. C'è un pennino per ogni tipo di pagina con i suoi campi specifici. C'è il NSArrayController principale nel file pennino principale, che sta popolando NSTableView. C'è un NSArrayController in ciascuno dei pennini specifici della pagina in modo che io possa associare i campi di dettaglio agli attributi della selezione corrente. Tutti i miei NSArrayController sono configurati in modo identico e li ho tutti associati allo stesso managedObjectContext e alla stessa selezioneIndex.

Sto usando il metodo di Aaron Hillegass per scambiare la vista che descrive nel suo libro su Cocoa. Quindi mi sono registrato per NSTableViewSelectionDidChangeNotifications e quando ne ricevo uno, chiama un metodo switchView:

switchView esamina l'oggetto attualmente selezionato, controlla che tipo di Pagina è e scambia il file pennino appropriato secondo il metodo di Hillegass.

Tutto funziona bene se aggiungo solo pagine di un tipo, ma non appena aggiungo una pagina di un secondo tipo, ottengo questo errore:

  

Errore nell'impostazione del valore per la selezione del percorso chiave Indici dell'oggetto (dall'entità oggetto associato: Pagina, numero di oggetti selezionati: 1): [valueForUndefinedKey:]: l'entità NoColPage non è conforme alla codifica del valore chiave per il lato chiave.

L'ultima parte dell'errore ha senso: è bloccato nel tentativo di visualizzare il pennino sbagliato, quindi sta cercando di legarsi a campi che non esistono per questo oggetto.

Ho aggiunto un campo selectionIndexes a MyDocument in modo che tutti i miei NSArrayController possano legarsi nello stesso posto. Mi sono angosciato per giorni e non riesco a capirlo. Qualche idea?

Se aiuta, ecco un progetto di esempio che puoi scaricare . Ho estratto solo le cose rilevanti per questo problema dal mio progetto in una nuova applicazione fittizia, che ho usato per testare e giocare.

PS: lo strumento Interface Builder per generare un'interfaccia master-detail da un'entità Core Data non funziona come vorrei per entità astratte. Crea solo campi per gli attributi nella superentitity.

Modifica: penso che Joshua sia interessato a qualcosa, ma sfortunatamente non funziona, continuo a riscontrare lo stesso problema. All'inizio stavo attraversando un momento difficile perché non avevo capito che -unbind: si aspetta una costante di stringa, non un percorso chiave.

Ho provato diverse varianti: dove tengo traccia del controller di array del pennino attualmente visualizzato; dove tengo traccia del tipo di pagina attualmente visualizzato e non mi separo / rilevo solo quando provo a visualizzare un tipo di pagina diverso ...

Ecco la sezione pertinente del codice.

-(void) displayViewController: (ManagingVC *) vc withClass:(NSString*) className {

//Try to end editing
NSWindow *w = [box window];
BOOL ended = [w makeFirstResponder:w];
if (!ended) {
    NSBeep();
    return;
}

//The Managing View Controller's NSArrayController
NSArrayController* vcAc = [vc arrCont];

//if the page we're trying to switch to is NOT the same type as the current page we're displaying
//if it is, do nothing.
if (![currPageDisplayed isEqual:className]) {

    //unbind the old view controller
    ManagingVC *oldvc = [viewControllers objectForKey:className];
    NSArrayController* oldsac = [oldvc arrCont];
    [oldsac unbind:@"selectionIndexes"];

    //bind the new view controller
    [vcAc bind:@"selectionIndexes" toObject:self withKeyPath:@"selectionIndexes" options:nil];
    currPageDisplayed = className;

    NSView *v = [vc view];

    //display the new view in an NSBox in the main nib
    [box setContentView:v];
}

}

È stato utile?

Soluzione 2

Dopo aver passato troppo tempo a cercare di sincronizzare ciascun controller di array NIB, ho rinunciato a questo approccio. L'unica cosa che ha funzionato per me è il controllo programmatico degli elementi della GUI visualizzati nel pennino principale e dei relativi collegamenti. Questo significa eliminare gli altri pennini. Questa non è davvero una soluzione sostenibile se stai lavorando con più di un paio di campi di testo, ma funziona per me in questo momento.

Seguo ancora il consiglio di Joshua di non associare prima di cambiare la vista, ma in questo momento sto solo legando i campi di testo a arrayController.selection.whateverKey

Altri suggerimenti

Il problema è che stai lasciando i controller dell'array dei pennini legati alla selezione del documento, il che li sta provando (quando la selezione cambia) a rappresentare l'elemento selezionato.

Prova questo:

  1. Rimuovi gli attacchi nei pennini.
  2. Prima di aggiungere una nuova vista, collega i suoi collegamenti nel codice.
  3. Prima di rimuovere la vista precedente, scollegare i relativi collegamenti nel codice.

Questo dovrebbe rendere tutto felice.

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