Pregunta

Apple tiene un pequeño y agradable tutorial para crear una interfaz simple maestro-detalle. Interface Builder incluso generará automáticamente uno para usted desde una entidad de Core Data. Sin embargo, estoy tratando de hacer algo más complicado que el simple ejemplo y he estado luchando por un tiempo para que funcione.

Tengo una aplicación basada en documentos Core Data. El modelo incluye una entidad abstracta Page, y varias subentidades concretas de Page. Todas las Páginas tienen algunos atributos en común (como " nombre ") y esos están definidos en Página. Obviamente, las subentidades tienen los atributos que son únicos para ellos.

Quiero que la interfaz le permita al usuario ver todos los tipos de páginas en la lista maestra (un NSTableView). Cuando seleccionan una página, los campos de detalles que se muestran dependerán del tipo de página que sea.

Esto es lo que tengo ahora:

Tengo un archivo de plumilla principal, donde se muestra la lista maestra, además de todos los campos comunes a una página. Hay una punta para cada tipo de página con sus campos específicos. Hay el principal NSArrayController en el archivo principal de la pluma, que está llenando el NSTableView. También hay un NSArrayController en cada una de las puntas específicas de la página para que pueda enlazar los campos de detalle a los atributos de la selección actual. Todos mis NSArrayControllers están configurados de forma idéntica, y los tengo todos vinculados al mismo managedObjectContext y al mismo selectionIndexes.

Estoy usando el método de Aaron Hillegass para el intercambio de vistas que describe en su libro Cocoa. Así que me registré para NSTableViewSelectionDidChangeNotifications, y cuando recibo una, llama a un método switchView:

switchView mira el objeto seleccionado actualmente, comprueba qué tipo de página es y cambia el archivo de plumilla apropiado de acuerdo con el método de Hillegass.

Todo funciona bien si solo agrego páginas de un tipo, pero tan pronto como agrego una página de un segundo tipo, aparece este error:

  

Valor de configuración de error para la selección de ruta clave Índices de objeto (de entidad objeto enlazado: Página, número de objetos seleccionados: 1): [valueForUndefinedKey:]: la entidad NoColPage no cumple con el valor de clave para el lado de la clave.

La última parte del error tiene sentido: está bloqueada intentando mostrar la punta incorrecta, por lo que trata de enlazar campos que no existen para este objeto.

Agregué un campo selectionIndexes a MyDocument para que todos mis NSArrayControllers pudieran enlazar al mismo lugar. He agonizado por esto durante días y no puedo entenderlo. ¿Alguna idea?

Si ayuda, aquí hay un proyecto de muestra que puede descargar . Extraje solo las cosas relevantes a este problema de mi proyecto en una nueva aplicación ficticia, que he estado usando para probar y jugar.

PS: la herramienta de Interface Builder para generar una interfaz maestra-detalle desde una entidad de Core Data no funciona como quiero que lo haga para entidades abstractas. Solo crea campos para los atributos en la superentidad.

Editar: Creo que Joshua está en algo, pero desafortunadamente, no funciona. Sigo encontrando el mismo problema. Al principio me estaba costando mucho porque no entendía eso: sin vinculación: espera una cadena constante, no una ruta clave.

He intentado varias variaciones: donde hago un seguimiento del controlador de matriz de la plumilla que se muestra actualmente; donde realizo un seguimiento del tipo de página que se muestra actualmente y solo desencuadro / revoco cuando intento mostrar un tipo de página diferente ...

Aquí está la sección relevante del código.

-(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];
}

}

¿Fue útil?

Solución 2

Después de pasar demasiado tiempo tratando de sincronizar el controlador de matriz de cada NIB, he renunciado a ese enfoque. Lo único que me ha funcionado es controlar mediante programación qué elementos de la GUI se muestran en la punta principal y sus enlaces. Esto significa eliminar las otras puntas. Esta no es realmente una solución sostenible si está trabajando con más que solo un par de campos de texto, pero funciona para mí en este momento.

Todavía sigo el consejo de Joshua de no enlazar antes de cambiar de vista, pero ahora solo estoy enlazando los campos de texto a arrayController.selection.whateverKey

Otros consejos

El problema es que está dejando los controladores de matriz de sus nibs enlazados a la selección del documento, lo que hace que intenten (cuando la selección cambia) representar el elemento seleccionado.

Prueba esto:

  1. Eliminar los enlaces en las puntas.
  2. Antes de agregar una nueva vista, conecte sus enlaces en el código.
  3. Antes de eliminar la vista anterior, desconecte sus enlaces en el código.

Esto debería mantener todo feliz.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top