Cargar una UITableViewCell reutilizable desde un plumín


Soy capaz de diseñar células UITableViewCells personalizadas y cargarlas bien utilizando la técnica descrita en el hilo encontrado en http://forums.macrumors.com/showthread.php?t=545061. Sin embargo, usar ese método ya no le permite iniciar la celda con un reuseIdentifier, lo que significa que tiene que crear instancias completamente nuevas de cada celda en cada llamada. ¿Alguien ha descubierto una buena manera de almacenar en caché tipos de celdas particulares para reutilizar, pero aún así poder diseñarlos en la interfaz ¿Constructor?

Author: Ronnie Liew, 2009-01-05

16 answers

Simplemente implemente un método con la firma del método apropiada:

- (NSString *) reuseIdentifier {
  return @"myIdentifier";
}
 74
Author: Louis Gerbarg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-05 18:21:49

En realidad, ya que está construyendo la celda en Interface Builder, simplemente establezca el identificador de reutilización allí:

IB_reuse_identifier

O si está ejecutando Xcode 4, verifique la pestaña Inspector de atributos:

introduzca la descripción de la imagen aquí

(Edit: Después de que su XIB sea generado por XCode, contiene una UIView vacía, pero necesitamos una UITableViewCell; por lo que debe eliminar manualmente la UIView e insertar una celda de vista de tabla. Por supuesto, IB no mostrará ningún parámetro UITableViewCell para un UIView.)

 119
Author: Tim Keating,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-08 14:11:32

Ahora, en iOS 5 hay un método UITableView apropiado para eso:

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
 66
Author: wzs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-10 11:45:52

No puedo recordar dónde encontré este código originalmente, pero ha estado funcionando muy bien para mí hasta ahora.

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"CustomTableCell";
    static NSString *CellNib = @"CustomTableCellView";

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
        cell = (UITableViewCell *)[nib objectAtIndex:0];
    }

    // perform additional custom work...

    return cell;
}

Ejemplo de configuración de Interface Builder...

Texto alternativo http://i32.tinypic.com/a9mnap.jpg

 47
Author: jrainbow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-19 02:05:27

Mira la respuesta que di a esta pregunta:

¿Es posible diseñar subclases NSCell en Interface Builder?

No solo es posible diseñar un UITableViewCell en IB, es deseable porque de lo contrario todo el cableado manual y la colocación de múltiples elementos es muy tedioso. Performaance está bien siempre y cuando tenga cuidado de hacer todos los elementos opacos cuando sea posible. El reuseID se establece en IB para las propiedades de la UITableViewCell, a continuación, se utiliza el coincidencia de ID de reutilización en el código al intentar desqueue.

También escuché de algunos de los presentadores en WWDC el año pasado que no debería hacer celdas de vista de tabla en IB, pero es una carga de litera.

 12
Author: Kendall Helmstetter Gelner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:53:17

A partir de iOS circa 4.0, hay instrucciones específicas en los documentos de iOS que hacen que esto funcione súper rápido:

Http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7

Desplácese hacia abajo hasta donde habla sobre la subclase UITableViewCell.

 7
Author: Ben Mosher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-17 21:31:21

Aquí hay otra opción:

NSString * cellId = @"reuseCell";  
//...
NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil];

for (id obj in nibObjects)
{
    if ([obj isKindOfClass:[CustomTableCell class]])
    {
        cell = obj;
        [cell setValue:cellId forKey:@"reuseIdentifier"];
        break;
    }
}
 6
Author: JDL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-27 11:09:18

Creo mis celdas de vista personalizadas de manera similar, excepto que conecto la celda a través de un IBOutlet.

El enfoque [nib objectAt...] es susceptible a cambios en las posiciones de los elementos en la matriz.

El enfoque UIViewController es bueno - solo lo probé, y funciona bastante bien.

PERO...

En todos los casos no se llama al constructor initWithStyle, por lo que no se realiza ninguna inicialización predeterminada.

He leído varios lugares sobre el uso de initWithCoder o awakeFromNib, pero no hay evidencia concluyente de que cualquiera de estos es el camino correcto.

Aparte de llamar explícitamente a algún método de inicialización en el método cellForRowAtIndexPath todavía no he encontrado una respuesta a esto.

 2
Author: sww,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-22 11:31:42

Hace un tiempo encontré una gran entrada de blog sobre este tema en blog.atebits.com , y desde entonces he comenzado a usar la clase Loren Brichter ABTableViewCell para hacer todas mis UITableViewCell.

Usted termina con un simple contenedor UIView para poner todos sus widgets, y el desplazamiento es muy rápido.

Espero que esto sea útil.

 2
Author: eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 00:18:53

Esta técnica también funciona y no requiere un ivar funky en su controlador de vista para la gestión de memoria. Aquí, la celda de vista de tabla personalizada vive en un xib llamado "CustomCell.xib".

 static NSData *sLoadedCustomCell = nil;

 cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
 if (cell == nil) 
 {
   if (sLoadedCustomCell == nil) 
   {        
      // Load the custom table cell xib
      // and extract a reference to the cell object returned
      // and cache it in a static to avoid reloading the nib again.

      for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil]) 
      {
        if ([loadedObject isKindOfClass:[UITableViewCell class]]) 
        {
          sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain];
          break;
        }
    }
    cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell];
  }
 2
Author: Bill Garrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-29 00:48:20

Louis Method funcionó para mí. Este es el código que uso para crear UITableViewCell desde el plumín:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];

    if (cell == nil) 
    {
        UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil];
        cell = (PostCell *)c.view;
        [c release];
    }

    return cell;
}
 2
Author: ggarber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-27 11:15:52
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *simpleTableIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}         

return cell;
}
 2
Author: Mohit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-01 05:29:41

La solución gustavogb no funciona para mí, lo que probé es:

ChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil];
[[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil];
cell = [c.blogTableViewCell retain];
[c release];

Parece funcionar. El blogTableViewCell es el IBOutlet para la celda y ChainesController es el propietario del archivo.

 1
Author: groumpf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-08 09:59:58

De los documentos de UITableView con respecto a dequeueWithReuseIdentifier: "Una cadena que identifica el objeto de celda a reutilizar. De forma predeterminada, el identificador de una celda reutilizable es su nombre de clase, pero puede cambiarlo a cualquier valor arbitrario."

Overriding-reuseIdentifer usted mismo es arriesgado. ¿Qué sucede si tiene dos subclases de su subclase de celda y usa ambas en una sola vista de tabla? Si envían la llamada reuse identifier a super, eliminarás una celda del tipo incorrecto.............. Creo que necesitas sobreescriba el método reuseIdentifier, pero haga que devuelva una cadena de identificador suplantada. O, si no se ha especificado uno, haga que devuelva la clase como una cadena.

 1
Author: SK9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-04 09:24:44

Por si sirve de algo, le pregunté a un ingeniero de iPhone sobre esto en una de las Charlas de tecnología de iPhone. Su respuesta fue: "Sí, es posible usar IB para crear células. Pero no. Por favor, no".

 0
Author: August,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-05 20:27:41

Seguí las instrucciones de Apple como vinculado por Ben Mosher (gracias!) pero encontró que Apple omitió un punto importante. El objeto que diseñan en IB es solo un UITableViewCell, al igual que la variable que cargan desde él. Pero si realmente lo configura como una subclase personalizada de UITableViewCell, y escribe los archivos de código para la subclase, puede escribir declaraciones IBOutlet y métodos IBAction en el código y conectarlos a sus elementos personalizados en IB. Entonces no hay necesidad de usar etiquetas de vista para acceder estos elementos y usted puede crear cualquier tipo de célula loca que desee. Es Cocoa Touch Heaven.

 0
Author: David Casseres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-22 21:02:50