tamaño sencillo personalizar para modificar imagenes editar con cambiar atributo macos cocoa nstableview osx-lion nsoutlineview

macos - sencillo - Enlace de NSOutlineView basado en vistas a datos principales



tooltip con imagenes (4)

Estoy tratando de implementar el nuevo OutlineView basado en vistas como una lista de fuentes en mi aplicación Mac. Sin embargo, no puedo mostrar los valores, así que hice una pequeña aplicación de prueba a partir de la plantilla de la aplicación Core Data, y tampoco puedo hacer que funcione allí.

Definí dos clases simples en mi modelo de datos; Llamémoslos "Padres" y "Niños". El padre tiene un atributo único, "nombre" y una relación única, "hijos". name es una cadena opcional, e children es una relación opcional de muchos a Child . El hijo tiene el mismo atributo de "nombre" y una relación de "padre" a uno que es la inversa de los niños . Generé clases personalizadas para ambos y escribí un talón en Niño para niños que devuelve nil .

Arrastre una lista de fuentes de la biblioteca de objetos a mi XIB y la coloqué en un controlador de árbol. La ruta de acceso de los hijos del controlador del árbol se establece en "hijos", se encuentra en el modo de nombre de entidad, con "Padre" como el nombre de la entidad, prepara el contenido seleccionado y su contexto de objeto gestionado se establece en el contexto del delegado de la aplicación. El Controlador de árbol es el origen de datos de la vista de esquema, y ​​enlazé la vista de texto de la celda de datos a la Vista de celda de tabla, con la ruta de la clave "objectValue.name".

en -applicationDidFinishLaunching: creo dos instancias principales, una con un hijo , y asigno la propiedad de nombre de cada objeto.

El problema actual

Ahora, con esa configuración fuera del camino, aparecen filas en la lista de fuentes, pero los campos de texto están vacíos, aunque estén enlazados. No creo que deba hacer nada más, ya que estoy usando enlaces, y estoy bastante seguro de que el enlace a la propiedad objectValue es lo correcto. ¿Qué va mal?

Puedo proporcionar más detalles si es necesario, pero estoy bastante seguro de que cubre todo lo que hice.


Como Boaz señaló anteriormente, debe implementar el método Delegar para devolver una vista.

Todo un misterio considerando que no pude encontrar ese método en los documentos.

Con respecto al tipo del parámetro del (id)item , es un NSTreeControllerTreeNode que es una subclase no documentada de NSTreeNode . Si lo lanzas, puedes obtener el objeto de la celda y devolver una vista diferente según el tipo de objeto, o los atributos de ese objeto determinan el tipo de vista de celda:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { NSTableCellView *view = nil; NSTreeNode *node = item; if ([node.representedObject isKindOfClass:[Group class]]) { view = [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self]; } else { view = [outlineView makeViewWithIdentifier:@"DataCell" owner:self]; } return view; }


Esto pareció ser un cambio para Xcode 4 o alrededor de eso. El generador de interfaz agrega dos objetos NSTableCellView debajo de NSOutlineView. Si elimina los objetos de NSTableCellView, regresará a un mundo más sensato (o al menos documentado) en el que necesita implementar los métodos:
outlineView:dataCellForTableColumn:item outlineView:willDisplayCell:forTableColumn:item

... o al menos lo haces si quieres una apariencia de lista de fuentes. En cualquier caso, así es como se configura el ejemplo de SourceView y por eso, cuando intenta recrear el ejemplo de SourceView que puede obtener en tal desorden.

Alternativamente, si desea continuar utilizando los objetos NSTableCellView (que son bastante útiles), entonces puede:

  • vincule el ''Contenido'' de NSOutlineView a su TreeController.arrangedObjects

  • vincule NSTextField (y / o NSImageView) bajo NSTableCellView a ''Table Cell View'' con una ruta de clave modelo de objectValue. <clave>


He creado un pequeño proyecto de muestra que también muestra un NSOutlineView , no con CoreData, pero el factor crucial es que, como @ boaz-stuller declaró que se seleccionó la celda correcta (similar a la forma en que maneja UITableViewCell en iOS).

Así que en mi caso he implementado el método así:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { if ([self isHeader:item]) { return [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self]; } else { return [outlineView makeViewWithIdentifier:@"DataCell" owner:self]; } }

Echa un vistazo a besi/mac-quickies en github. La mayoría de las cosas se realizan en IB o se pueden encontrar en el AppDelegate


Wow, es como yo desde hace dos semanas está haciendo esta pregunta.

De todos modos, si eres como yo, el problema es que,
para NSOutlineViews basado en NSOutlineViews , necesita implementar el

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item;

delegar el método y devolver el NSTableCellView que configuró,
o simplemente te darán una línea en blanco. La forma más fácil de hacer esto es simplemente llamar

[outlineView makeViewWithIdentifier:@"MyCell" owner:self]

reemplazar MyCell con lo que haya escrito como "Identificador de elemento de la interfaz de usuario"
en el inspector de identidad para su NSTableCellView .

C objetivo:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { return [outlineView makeViewWithIdentifier:@"MyCell" owner:self]; }

Rápido:

func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { return outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("MyCell"), owner: self) }

ACTUALIZACIÓN 2018-08-02:

En realidad, no es necesario establecer el delegado. Así es como lo hice funcionar (probado con NSTreeController , pero también debería funcionar con NSArrayController ):

  • Enlazar cada objeto de columna a arrangedObjects (sin ruta de clave de modelo)
  • Enlace la vista personalizada más interna (por ejemplo, campo de etiqueta) a objectValue.yourCustomValue
  • No debería ser necesario, pero si esto no funciona, intente configurar el identificador para la columna y para el TableCellView . Asegúrese de que ambos identificadores sean idénticos. Repita eso para las columnas restantes con diferentes identificadores.

Captura de pantalla: enlaces para vista basada en NSOutlineView