Pregunta

Quiero ocultar/mostrar dinámicamente algunas de las columnas en un NSTableView, según los datos que se mostrarán; básicamente, si una columna está vacía, me gustaría que esté oculta.Actualmente estoy completando la tabla con una clase de controlador como delegado de la tabla.

¿Algunas ideas?Veo que puedo configurar la columna oculta en Interface Builder, sin embargo no parece ser un buen momento para revisar las columnas y verificar si están vacías o no, ya que no parece haber un método que lo esté. Se llama antes/después de que se completen todos los datos de la tabla.

¿Fue útil?

Solución

Una NSTable es solo la clase que pinta la tabla.Como usted mismo dijo, tiene una clase que le da a la tabla como delegada y esta clase alimenta la tabla con los datos para mostrar.Si almacena los datos de la tabla como NSArray dentro de su clase delegada, debería ser fácil saber si una columna está vacía, ¿no es así?Y NSArray le pregunta a su clase a través del método delegado cuántas columnas hay, entonces, cuando se le pregunta, ¿por qué no buscar cuántas columnas tiene datos e informar ese número en lugar del número real de columnas que almacena internamente y luego cuando se le solicita? proporcionando los datos para (columna, fila), simplemente omita la columna vacía.

Otros consejos

En Mac OS X v10.5 y posteriores, existe la setHidden: selector para NSTableColumn.

Esto permite que las columnas se oculten/muestren dinámicamente con el uso de identificadores:

NSInteger colIdx;
NSTableColumn* col;

colIdx = [myTable columnWithIdentifier:@"columnIdent"];
col = [myTable.tableColumns objectAtIndex:colIdx];
[col setHidden:YES];

He hecho esto con enlaces, pero configurándolos mediante programación en lugar de hacerlo a través de Interface Builder.

Este pseudofragmento debería darle una idea general:

NSTableColumn *aColumn = [[NSTableColumn alloc] initWithIdentifier:attr];
[aColumn setWidth:DEFAULTCOLWIDTH];
[aColumn setMinWidth:MINCOLWIDTH];
[[aColumn headerCell] setStringValue:columnLabel];

[aColumn bind:@"value"
     toObject:arrayController 
  withKeyPath:keyPath 
  options:nil];             

[tableView addTableColumn:aColumn];
[aColumn release];

Por supuesto, también puedes agregar formateadores y todo eso.

No funciona en Interface Builder.Sin embargo, funciona programáticamente.Así es como vinculo una NSTableViewColumn con el identificador "Estado" a una clave en mi NSUserDefaults:

Rápido:

tableView.tableColumnWithIdentifier("Status")?.bind("hidden", toObject: NSUserDefaults.standardUserDefaults(), withKeyPath: "TableColumnStatus", options: nil)

C objetivo:

[[self.tableView tableColumnWithIdentifier:@"Status"] bind:@"hidden" toObject:[NSUserDefaults standardUserDefaults] withKeyPath:@"TableColumnStatus" options:nil];

No tengo una respuesta completa en este momento, pero busque en Enlaces.Generalmente es posible hacer todo tipo de cosas con Cocoa Bindings.

No hay ningún enlace de visibilidad para NSTableColumn, pero es posible que pueda establecer el ancho en 0.

Luego puede vincularlo al marcador de posición nulo y establecer este valor en 0, pero no olvide establecer los otros marcadores de posición en valores razonables.

(Como dije, esto es sólo el comienzo, puede que necesite algunos ajustes).

No hay un momento único para completar todos los datos.NSTableView no almacena datos, los solicita dinámicamente desde su fuente de datos (u objetos vinculados si está utilizando enlaces).Simplemente extrae datos que obtiene de la fuente de datos y los descarta.No debería ver la tabla solicitando datos para cualquier cosa que no esté visible, por ejemplo.

¿Parece que estás usando una fuente de datos?Cuando los datos cambian, es su responsabilidad llamar -reloadData en la tabla, lo cual es un nombre poco apropiado.Es más como "invalidar todo".

Es decir, ya deberías saber cuándo cambian los datos.Ese es el punto en el que puedes calcular qué columnas deben ocultarse.

@amrox: si entiendo tu sugerencia correctamente, ¿estás diciendo que debería vincular un valor a la propiedad oculta de NSTableColumns en mi tabla?Parece que funcionaría, sin embargo, no creo que NSTableColumn tenga una propiedad oculta, ya que los mensajes isHidden y setHidden controlan la visibilidad de la columna, lo que me dice que esto no es una propiedad, a menos que me falte algo. (lo cual es bastante posible).

Me gustaría publicar mi solución actualizada para Swift 4 usando enlaces Cocoa y el archivo real isHidden bandera sin tocar el ancho de las columnas (ya que es posible que necesite restaurar el valor original después...).Supongamos que tenemos una casilla de verificación para alternar la visibilidad de algunas columnas (o siempre puede alternar la visibilidad). hideColumnsFlag variable en el ejemplo siguiente de cualquier otra forma que desee):

class ViewController: NSViewController {

     // define the boolean binding variable to hide the columns and use its name as keypath
     @objc dynamic var hideColumnsFlag = true

     // Referring the column(s)
     // Method 1: creating IBOutlet(s) for the column(s): just ctrl-drag each column here to add it
     @IBOutlet weak var hideableTableColumn: NSTableColumn!
     // add as many column outlets as you need...

     // or, if you prefer working with columns' string keypaths
     // Method 2: use just the table view IBOutlet and its column identifiers (you **must** anyway set the latter identifiers manually via IB for each column)
     @IBOutlet weak var theTableView: NSTableView! // this line could be actually removed if using the first method on this example, but in a real case, you will probably need it anyway.

     // MARK: View Controller Lifecycle

     override func viewDidLoad() {
         super.viewDidLoad()

         // Method 1
         // referring the columns by using the outlets as such:
         hideableTableColumn.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column outlet.

         // Method 2
         // or if you need/prefer to use the column identifiers strings then:
         // theTableView.tableColumn(withIdentifier: .init("columnName"))?.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column identifier you have set.

         // obviously use just one method by commenting/uncommenting one or the other.
     }

     // MARK: Actions

     // this is the checkBox action method, just toggling the boolean variable bound to the columns in the viewDidLoad method.
     @IBAction func hideColumnsCheckboxAction(_ sender: NSButton) {
         hideColumnsFlag = sender.state == .on
     }
}

Como habrás notado, todavía no hay manera de vincular el Hidden bandera en Interface Builder como en XCode10:puedes ver el Enabled o Editable enlaces, pero sólo mediante programación tendrá acceso a la isHidden bandera para la columna, como se llama en Swift.

Como se indicó en los comentarios, el segundo método se basa en los identificadores de columna que debe configurar manualmente a través de Interface Builder en el campo Identidad después de seleccionar las columnas relevantes o, si tiene una serie de nombres de columnas, puede enumerar las columnas de la tabla y asignar las identificadores así como los enlaces en lugar de repetir líneas de código similares.

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