cocoa operating-system nstableview nsbuttoncell

cocoa - El tipo NSButtonCell of Check dentro de NSTableView no permite que se modifique el valor



operating-system (1)

Tengo ventana con 3 vistas de tabla (10.7.2, Xcode 4.2). Todos están creados en IB y NSButtonCells están conectados con puntos de venta.

Creé la clase de controlador y llené las tres vistas con algunos datos de muestra:

- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView { return 10; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { NSButtonCell *buttonCell; if(aTableView == dimensionTable) { [dimensionButtonCell setTitle:@"Dimension"]; buttonCell = dimensionButtonCell; } else if(aTableView == shopTable) { [shopButtonCell setTitle:@"Shop"]; buttonCell = shopButtonCell; } else if(aTableView == countryTable) { [countryButtonCell setTitle:@"Country"]; buttonCell = countryButtonCell; } return buttonCell; }

Tengo 2 preguntas:

  1. No puedo cambiar el estado de la casilla de verificación a través de GUI. Sin embargo, puedo cambiarlo programáticamente. Parpadea un poco, cuando mantienes presionado el botón del mouse, pero no permite el cambio ...

  2. Traté de llenar los datos como con las vistas, sin salidas a las celdas. No funcionó. ¿Las celdas NSButtonCell dentro de las vistas de celda son de alguna manera diferentes como Vistas de tabla basadas en vistas o Vistas de tabla basadas en cel "normales"?


Después de una larga lucha, logro encontrar la solución al problema. Una parte del problema era un simple error en el lado del modelo de datos, pero no era crucial, algo mucho más difícil de hacer con el delegado de NSTableView y el origen de datos.

Hubo principalmente 3 dificultades que impidieron una buena comprensión y la gestión de este problema:

  • La documentación de Apple carece de cualquier explicación razonable sobre las diferencias y el uso típico de - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex en la fuente de datos de la vista de tabla y - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row de su delegado. Si bien puede parecer que necesitarías este último método, porque NSButtonCells son NSCells personalizadas, resulta que no es necesario, pero de todos modos lo dejé al final.

  • conversiones internas en los métodos NSTableView

  • problema no está documentado casi en cualquier lugar de la red

Aquí hay pasos que debes hacer:

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { buttonCell = [aTableColumn dataCell]; NSString *columnKey = [aTableColumn identifier]; return buttonCell; }

Puede ver que este método debe implementarse ya sea que lo use o no.

- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { buttonCell = [tableColumn dataCell]; NSString *columnKey = [tableColumn identifier]; if(tableView == dimensionTable) { // returnObject = @"Dimension"; // [dimensionButtonCell setTitle:@"Dimension"]; // buttonCell = dimensionButtonCell; } else if(tableView == shopTable) { [buttonCell setState:[[mySelectedShops objectAtIndex:row] integerValue]]; [buttonCell setTitle:[myShops objectAtIndex:row]]; } else if(tableView == countryTable) { [buttonCell setState:[[mySelectedCountries objectAtIndex:row] integerValue]]; [buttonCell setTitle:[myCountries objectAtIndex:row]]; } return buttonCell; }

se puede ver que usé el segundo método, sin embargo, objectValueForTableColumn podía usar. También puede ver, tengo NSMutableArray mySelectedShops y mySelectedCountries para contener NSInteger (1 o 0) envuelto en NSNumber para cada fila en Table View.

Si configura el estado o valor entero de NSCell, no hay diferencia. Ambos verificarán y desmarcarán NSButtonCell con los valores 1 o 0 del tipo NSInteger.

- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { NSString *columnKey = [aTableColumn identifier]; if(aTableView == dimensionTable) { // [dimensionButtonCell setTitle:@"Dimension"]; // buttonCell = dimensionButtonCell; } else if(aTableView == shopTable) { [mySelectedShops replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]]; } else if(aTableView == countryTable) { [mySelectedCountries replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]]; } }

Aunque pasé el valor NSInteger al objeto NSCell, anObject aquí es del tipo __NSCFBoolean, lo que significa que algo no funciona como se esperaba. Para poder reemplazar el valor del objeto a las matrices, lo he convertido en NSCell solo para obtener valores enteros. En realidad, funciona sin yeso también, por lo que es otro misterio para mí, pero me gusta más de esa manera.

Está claro que Apple se está moviendo para ver celdas basadas como en UITableView. Aún así, espero que esto ayude a alguien.