Copiando UITableViewCell

votos
7

Estoy leyendo una celda de tabla personalizada tableView:cellForRowAtIndexPath:desde un archivo de punta. Esto funciona muy bien para mis propósitos, excepto que es bastante lento.

Ahora, sé que lo correcto a largo plazo es crear la celda completamente en código, y usar una sola vista, y así sucesivamente. Pero este es un prototipo, y no quiero poner tanto esfuerzo en ello.

Por ahora, me alegraría si estuviera leyendo el plumín solo una vez en la UIViewControllersubclase, y luego tableView:cellForRowAtIndexPath:hice copias de él. Mi suposición aquí es que copiar sería más rápido que leer el plumín.

Esto es lo que uso para cargar el plumín, al que llamo desde viewDidLoad:(y retaindespués)

-(id)loadFromNamed:(NSString*)name {
    NSArray *objectsInNib = [[NSBundle mainBundle] loadNibNamed:name
                                                          owner:self
                                                        options:nil];
    assert( objectsInNib.count == 1 );
    return [objectsInNib objectAtIndex:0];
}

Todo está bien hasta ahora. Pero la pregunta es: ¿cómo copio esto una y otra vez? ¿Es posible?

Probé [_cachedObject copy]y [_cachedObject mutableCopy]aunque UITableViewCellno apoya ninguno de estos protocolos de copia.

Si tengo que hacerlo, puedo decirles que ignoren la velocidad hasta que esté preparado para retirar la punta por completo, pero prefiero que funcione un poco más rápido si aquí hay una fruta fácil de encontrar.

¿Algunas ideas?

Publicado el 20/02/2009 a las 21:43
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
8

Creo que hacer frente de celda de la tabla se puede utilizar junto con el mecanismo de desencola, lo que permitirá crear células una vez (a partir de cacao o mediante programación o conseguir que se carga automáticamente desde otra punta y la vinculación como una salida en IB) y luego clonar o quitar de la cola se cuando sea necesario.

UITableViewCell no se ajusta al protocolo NSCopying, pero soporta el archivado enchavetado / mecanismo unarchiving, por lo que se puede utilizar para la clonación.

"En base a la respuesta ? ¿Cómo duplicar un UIButton en Objective C " mi método delegado fuente de datos se parece a:

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

    if (!cell) {
        NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell];
        cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
    }

    // ... config ...

    return cell;
}

Y en mi caso self.tableViewCell es una célula que se ha cargado una sola vez desde el archivo punta de vista.

No probé lo que será más rápido: "archivo + desarchivar" para clonar o "archivo de punta de carga + desarchivar" qué marco va a hacer en caso de -loadNibNamed: Propietario: Opciones: , he utilizado este método sólo con consideraciones de conveniencia, pero buenas posibilidades de que la operación de memoria vs operación de archivo serán más rápidos.

EDIT: No parece tan fácil como parecía al principio. Como UIImage no se ajusta a NSCoding, las células con UIImageViews configurados no pueden ser simplemente copiados sin código adicional. Sí, la copia de la imagen entera definitivamente no es una buena práctica, aplausos a Apple para señalar esto.

Respondida el 17/03/2011 a las 13:00
fuente por usuario

votos
6

Use la clonación de celda integrada en la vista de tabla. Apple sabía que generar muchas células de tabla era lento. Consulte los documentos para este método:

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier

Usted crea la celda una vez, luego cuando se soliciten nuevas celdas, use ese método para clonar las celdas existentes. Luego solo cambia lo que necesita cambiarse sobre la nueva celda y devuelve el objeto de celda.

También consulte el código de muestra de la vista de tabla proporcionado por Apple que utiliza este método y le muestra el camino correcto. El hecho de que tu celda fue cargada desde una punta no debería importar en absoluto.


Aclaración menor: no creo que el método anterior clone células para ti. En su lugar, se necesita un objeto de celda que se haya desplazado de la pantalla y simplemente los mueva a un lugar nuevo. Entonces, literalmente, está reutilizando una celda. Por lo tanto, asegúrese de que la vista de tabla personalizada se pueda establecer en todos los valores nuevos que necesite fuera de la inicialización.

Respondida el 20/02/2009 a las 22:11
fuente por usuario

votos
4

No estoy orgulloso de esta solución, pero funciona con la mayor cantidad posible de enlaces IB:

Interfaz (AlbumTableViewCell es una subclase de UITableViewCell de la cual se define una instancia en el archivo XIB de AlbumViewController):

@interface AlbumsViewController : UITableViewController {
    IBOutlet AlbumTableViewCell *tableViewCellTrack;
}

@property (nonatomic, retain) AlbumTableViewCell *tableViewCellTrack;

Implementación (unarchive / archive hace una copia / clona la celda de la vista de tabla):

@implementation AlbumsViewController

@synthesize tableViewCellTrack;

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

    if (cell == nil) {
        AlbumsViewController *albumsViewController = [[[AlbumsViewController alloc] init] autorelease];
        [[NSBundle mainBundle] loadNibNamed: @"AlbumsViewController" owner: albumsViewController options: nil];

        cell = albumsViewController.tableViewCellTrack;
    }

    cell.labelTitle.text = ...;
    cell.labelArtist.text = ...;

    return cell;
}
Respondida el 08/12/2009 a las 10:06
fuente por usuario

votos
3

Bueno, no estoy seguro de por qué todos los tutoriales no especifican este paso.

Al usar su propia UITableViewCell desde Nib, no es suficiente llamar dequeueReusableCellWithIdentifier. Debe especificar el "Identificador" en el IB, solo para ello en la sección de la pestaña Celda de vista de tabla.

Luego, asegúrese de que el identificador que ingresó en IB sea el mismo que el identificador que utiliza para dequeueReusableCellWithIdentifier.

Respondida el 17/06/2009 a las 05:10
fuente por usuario

votos
1

Aquí está en Swift

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell : UITableViewCell?
    let cellId = String(format: "Cell%d", indexPath.row)
    cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell?

    if cell == nil {
        let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!)
        cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell?
    }

    // do some stuff

    return cell!
}
Respondida el 23/10/2015 a las 23:00
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more