2008-10-14 7 views
22

Estoy tratando de subclase NSCell para su uso en un NSTableView. La celda que quiero crear es bastante complicada, por lo que sería muy útil si pudiera diseñarla en Interface Builder y luego cargar NSCell desde una punta.¿Es posible diseñar subclases NSCell en Interface Builder?

¿Esto es posible? ¿Cómo lo hago?

+0

Ahora que NSTableView es compatible con NSTableCellView, me pregunto si existe una forma mejor de ayudar a hacer todo lo posible desde IB. – tofutim

Respuesta

0

lo hago de esta manera:

/* example of a silly way to load a UITableViewCell from a standalone nib */ 

+ (CEntryTableViewCell *)cell 
{ 
// TODO -- this is really silly. 
NSArray *theObjects = [[NSBundle mainBundle] loadNibNamed:@"EntryTableViewCell" owner:self options:NULL]; 
for (id theObject in theObjects) 
    if ([theObject isKindOfClass:self]) 
     return(theObject); 
NSAssert(NO, @"Could not find object of class CEntryTableViewCell in nib"); 
return(NULL); 
} 

Sin embargo, no es muy eficiente y si va a cargar gran cantidad de datos que le puede hacer daño. Por supuesto, debería usar un reuseIdentifier que debería obligar a este código a ejecutarse solo unas pocas veces por tabla.

+1

La pregunta era para Cocoa, no Cocoa Touch – srgtuszy

5

En IB, inicie un XIB vacío. Ahora vaya a la paleta y arrastre en una UITableViewCell, haga doble clic para abrir y editar. incluyen solo el UITableViewCell personalizado (ningún otro UIViews u otros controles de nivel superior) - asegúrese de que es un UITableViewCell real en IB, o no puede establecer un identificador de reutilización (en lugar de convertir un UIView en IB como su clase UITableViewCell personalizada) Luego puede agregar etiquetas o lo que quiera dentro de la celda, así como establecer el identificador de reutilización o establecer el indicador de divulgación que desee.

de usar, se proporciona un código como éste en el tableView: cellForRow: atIndexPath: Método:

YourCustomCellClass *cell = (YourCustomCellClass *)[tableView dequeueReusableCellWithIdentifier:<IDYouSetInXIBFile>]; 
if (cell == nil) 
{ 
     NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:<YourXIBName> owner:self options:nil]; 
    id firstObject = [topLevelObjects objectAtIndex:0]; 
    if ([ firstObject isKindOfClass:[UITableViewCell class]]) 
     cell = firstObject; 
    else cell = [topLevelObjects objectAtIndex:1]; 
} 

Si tiene alguna etiquetas u otros controles que desea hacer referencia en su código, los cables en IB su clase de celda personalizada, NO el propietario del archivo, que no necesita establecer con el código anterior (puede dejarlo como NSObject).

Editar: Noto que realmente está buscando una respuesta NSCell, pero el enfoque del código para usar IB debe ser idéntico en Cocoa con el código Cocoa Touch que utilicé arriba ya que loadNibNamed es una llamada Cocoa estándar.

+0

De alguna manera lo hice mal la primera vez, pero sus instrucciones detalladas (el comienzo) salvó el día. Gracias! – JOM

+6

Aquí tienes el sistema operativo incorrecto. No es Cocoa Touch. – Domness

11

La pregunta era sobre una subclase de NSCell; las otras respuestas parecen estar haciendo otra cosa, probablemente aprovechando que UITableViewCell sea una vista.

NSCell no es una vista. Si bien establecer una celda personalizada en IB sería una cosa útil para poder hacer, creo que la respuesta es básicamente "no, esto no es posible". Cuando subclasifica NSCell, simplemente está haciendo su propio dibujo. No hay subcélulas de soporte ni configuración automática parametrizada (en los resortes y puntales NSView), que sospecho que es lo que está buscando.

La única advertencia es que podría diseñar una subclase NSCell que hiciera hacer el diseño de los subelementos y los parámetros proporcionados para establecer esos subelementos y todos los parámetros ajustables. Luego, necesitaría escribir un complemento de IB para que esa celda y el inspector de acompañamiento estén disponibles en IB en el momento del diseño.

Esto, sin embargo, es probablemente más difícil que escribir una pequeña aplicación personalizada que hace más o menos lo mismo. Ponga un NSCell en un control en el medio de una ventana y conviértase en UI para ajustar los parámetros que le interesan. Los enlaces pueden hacer esto bastante sencillo para posicionar cosas (es decir, vincular un valor x a un control deslizante), aunque lo hará no obtener la manipulación directa de los elementos, por supuesto. Cuando hayas terminado, puedes archivar tu celda y cargar el archivo en tiempo de ejecución en tu aplicación real, o simplemente puedes desconectar las propiedades y configurarlas en el código de tu aplicación.

2

Joar Wingfors escribió un artículo para Stepwise hace unos años sobre un tema relacionado, Subviews in TableView Rows.

La técnica principal es crear un NSCell que pueda alojar un NSView. Si hicieras esto, podrías diseñar una subclase NSView en Interface Builder que puedas insertar en cualquier lugar donde necesites esa celda específica.

Otra posibilidad, si puede apuntar a Leopard, es ver si necesita usar un NSTableView o si puede usar un NSCollectionView. Las vistas de colección tratan directamente en términos de "vistas de elementos" en lugar de en celdas, por lo que son mucho más sencillas de diseñar en Interface Builder.

7

dice como Ken, NSCells y NSViews son diferentes, y sólo se puede establecer jerarquías en NSView SEMILLA, no NSCells (que no tienen ningún tipo de jerarquía explícita).

Por otro lado, no hay nada que le impide tener una jerarquía de NSViews y utilizarlo para llamar su NSCell - se puede añadir como una subvista de vista de los padres de su celular, diles a mostrar, y eliminarlos de la ventana y nadie sería más sabio.

En este caso, usar un NIB funcionaría, aunque parece una tonelada de molestia. Normalmente, acabo de reemplazar el objeto que toma NSCells por uno personalizado que toma mi NSViews, pero eso significa escribir tu propio código de manejo del mouse, que es muy delicado.

Por otro lado, mi enfoque permite enlazar los valores de las vistas en NIB, por lo que no tiene que hacer ningún trabajo adicional, lo cual es genial.

-1

Haz tu UITableViewCell a su tableviewcontroller y declarar una propiedad IBOutlet:

@interface KuguTableViewController : UITableViewController { 
    IBOutlet UITableViewCell *customTypeCell; 
} 

@property (readonly) UITableViewCell *customTypeCell; 

... entonces en cellForRowAtIndexPath sólo puede utilizar su celular y ponerlo a ser reutilizado:

static NSString *CellIdentifier = @"CustomCell" 
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
     cell = customTypeCell; 
     cell.reuseIdentifier = CellIdentifier; 
+0

Aquí tienes el sistema operativo incorrecto. – Domness

+0

no merece un menos. – evdude100

11

Algunos Las respuestas en este hilo han salido del tema porque están hablando de Cocoa Touch, cuando la pregunta original era sobre Cocoa: las 2 API son bastante diferentes en este aspecto y Cocoa Touch lo hace fácil porque UITableViewCell es av iew subclass. NSCell no lo es, y ese es el problema

Para más información, tuve que hacer algo muy similar en NSOutlineView recientemente, que es básicamente lo mismo, pero un poco más difícil porque tienes que lidiar con la divulgación/colapso de niveles . Si usted está interesado en el código, he publicado sobre ello aquí: http://www.stevestreeting.com/2010/08/08/cocoa-tip-using-custom-table-outline-cells-designed-in-ib/

HTH

+0

exactamente lo que estaba buscando –

1

he encontrado algunos ejemplos interesantes que no entiendo totalmente, sin embargo.

Las 2 últimas ejemplos trabajan con NSTableViewDataSource y NSTableViewDelegate. Me gustaría usar Bindings y ArrayController en el InterfaceBuilder para conectar otros elementos de la IU como campos de texto.

0

1) Crear NSViewControllerTableViewCell.h

2) Crea en TableViewCell.h algunos procedimientos como

-(void)setText:(NSString *)text image:(NSImage *)image 

3) en la clase principal #import "TableViewCell.h"

4) En la clase principal de -(NSView *)tableView:viewForTableColumn:row: write:

NSImage *img = //some image 
TableViewCell *cell = [[TableViewCell alloc] initWithWindowNibName:@"TableViewCell"]; 
cell.view.init; 
[cell setText:@"some text" image:img]; 
return cell; 

Espero que esto ayude =)

0

Quiero ofrecer un enfoque más moderno aquí.

A partir de iOS 5, UITableView tiene un método

(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier

Una vez que registró su SEMILLA que contiene su celular, sólo tiene que utilizar

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier

para obtener una nueva célula. Si una celda está disponible para su reutilización, se devolverá; de lo contrario, se creará automáticamente una nueva celda, y en ese caso esto significa que se cargará desde el archivo NIB.

Cuestiones relacionadas