ios - tablas - uitableview tutorial swift 4
¿Cómo puedo acelerar un UITableView? (9)
use una instancia de imagen compartida para el fondo (asigne / inicie / suelte uno por cada vez que se cree una nueva celda). Cuando la vista de la tabla es grande, esto significa que las celdas X de fondo en la memoria requieren mucha más memoria de la que deberían.
en lugar de
cell.backgroundView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell gradient2.png"]];
Solo usa :
cell.backgroundView= [SomeHelperClass sharedBackgroundUIImageResource];
Si eso no ayuda, usa CG en lugar de etiquetas y otras subvistas (una captura de pantalla te ayudará aquí ... para saber de qué estamos hablando).
Tengo un UITableView con aproximadamente 400 celdas en 200 secciones y es un poco lento para responder a la interacción del usuario (desplazamiento, selección de celdas). No creo que esté haciendo nada fuera de lo normal para hacerlo lento. Las celdas y los encabezados solo tienen una imagen de fondo y texto. ¿Alguien más ha tenido este tipo de problema, y conoce alguna forma de hacerlo correr un poco más rápido?
Edición: ofrezco una recompensa porque me encantaría recibir comentarios útiles sobre esto. No creo que la respuesta esté en un problema en mi código. En su lugar, estoy buscando estrategias para volver a diseñar el UITableView para que funcione más rápido. Estoy totalmente abierto a agregar nuevos códigos y espero escuchar lo que ustedes tienen que decir.
La lentitud se observa tanto en el simulador como en mi dispositivo, un iPhone 4. Aquí están mis implementaciones de viewForHeaderInSection
y cellForRowAtIndexPath
, que son los únicos métodos UITableViewDelegate
implementados de forma no trivial. Estoy reutilizando celdas y vistas de cabecera.
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger) section
{
HaikuHeaderView* view= [m_sectionViews objectAtIndex:section];
NSMutableArray* array= [m_haikuSearch objectAtIndex:section];
Haiku* haiku= [array objectAtIndex:0];
[view.poetLabel setText:[haiku nameForDisplay]];
return view;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
cell.backgroundView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell gradient2.png"]];
// (Set up a bunch of label attributes in the cell...)
}
NSMutableArray* array= [m_haikuSearch objectAtIndex:indexPath.section];
Haiku* haiku = [array objectAtIndex:indexPath.row];
cell.textLabel.text = [haiku.m_lines objectAtIndex:0];
return cell;
}
¿El delegado de la vista de tabla implementa?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Si es así, es posible que desee considerar la configuración de la propiedad rowHeight de su UITableViewCell en su lugar.
¿Estás usando muchas subvistas?
Si es así, una buena técnica es, en lugar de agregar muchas etiquetas e imágenes, dibujarlas utilizando CoreGraphics.
Para hacer esto, tendría que subclasificar UITableViewCell e implementar el método -(void)drawRect:(CGRect)rect
.
Dos sugerencias: una es usar -initWithStyle:reuseIdentifier:
para las celdas de la vista de tabla en lugar de -initWithFrame :. La otra es comentar la configuración de cell.backgroundView en una imagen con un degradado y ver si ese es el culpable. Cada vez que he tenido un bajo rendimiento en una vista de tabla ha sido debido a una imagen.
Este es un pequeño tema fuera de tema aquí (porque solo tiene una imagen de fondo para todas las celdas):
Mi aplicación muestra diferentes imágenes en cada celda. Después de agregar aproximadamente 5 celdas a UITableView, la tabla se ralentiza drásticamente. Se tarda entre 1 y 2 segundos en procesar todas las imágenes cada vez que abro el controlador de vista.
if let image = UIImage(contentsOfFile: photoFile){
// just set it and let system fit it
//cell.imageView!.image = image
// 1 - Calculate sized
let DEFAULT_THUMBNAIL_WIDTH: CGFloat = (cellHeight / 4) * 5;
let DEFAULT_THUMBNAIL_HEIGHT: CGFloat = cellHeight;
let aspectRatio: CGFloat = image.size.width / image.size.height
var willBeHeight = DEFAULT_THUMBNAIL_HEIGHT
var willBeWidth = DEFAULT_THUMBNAIL_HEIGHT * aspectRatio
if(willBeWidth > DEFAULT_THUMBNAIL_WIDTH){
willBeWidth = DEFAULT_THUMBNAIL_WIDTH
willBeHeight = willBeWidth / aspectRatio
}
let eps:CGFloat = 0.000001
assert((willBeHeight - eps) <= DEFAULT_THUMBNAIL_HEIGHT);
assert((willBeWidth - eps) <= DEFAULT_THUMBNAIL_WIDTH);
// 2 - Create context
var size:CGSize = CGSize(
width: DEFAULT_THUMBNAIL_WIDTH,
height: DEFAULT_THUMBNAIL_HEIGHT)
UIGraphicsBeginImageContext(size)
// one-to-one rect
//var imageRect: CGRect = CGRectMake(0.0, 0.0, size.width, size.height)
var imageRect: CGRect = CGRectMake(0.0, 0.0, willBeWidth, willBeHeight)
// 3 - Draw image
image.drawInRect(imageRect)
var imageResult: UIImage = UIGraphicsGetImageFromCurrentImageContext()
cell.imageView!.image = imageResult
UIGraphicsEndImageContext()
}else{
DDLogError("Can not draw photo: /(photoFile)")
}
Así que he terminado generando pequeños THUMBNAILS para todas mis imágenes.
Incluso si su celda es realmente tan simple (imagen de fondo y etiqueta) hay algunas cosas que debe considerar
Almacenamiento de imágenes en caché Esto es lo más obvio: si está utilizando la misma imagen en todas partes, cárguela una vez en el UIImage y reutilícela. Incluso si el sistema lo almacena en caché por su cuenta, el uso directo del ya cargado nunca debería hacer daño.
Cálculo rápido Otra cosa bastante obvia: hacer que el cálculo de la altura y el contenido sea lo más rápido posible. No realice búsquedas sincrónicas (llamadas de red, lecturas de disco, etc.).
Canal alfa en la imagen. Lo que es caro cuando el dibujo es la transparencia. Como el fondo de la celda no tiene nada detrás, asegúrate de guardar tu imagen sin canal alfa. Esto ahorra mucho procesamiento.
Etiqueta transparente Lo mismo se aplica a la etiqueta en la parte superior de su vista de fondo, desafortunadamente, hacerla opaca puede arruinar el aspecto de su celda, pero depende de la imagen.
Celda personalizada En general, la subclasificación de UITableViewCell
y la implementación de drawRect:
usted mismo es más rápido que la construcción de la jerarquía de subvistas. Puede convertir su imagen en una variable de clase que utilizan todas las instancias. En drawRect:
dibujarías la imagen y el texto sobre ella.
Verificar composición El simulador tiene una herramienta para resaltar las partes que son costosas debido a la transparencia (el verde está bien, el rojo es una mezcla alfa). Se puede encontrar en el menú de depuración: "Color Blended Layers"
Lo mejor que puedes hacer si buscas acelerar tu código es perfilarlo. Hay dos razones para esto:
Puede leer sobre algunas cosas que mejorarán el rendimiento de la tabla en general, como usar celdas de altura fija y reutilizar las celdas, y probablemente ayude a implementar esas cosas (parece que ya lo ha hecho). Pero cuando se trata de acelerar su código, realmente necesita saber dónde está gastando la mayor parte de su tiempo la aplicación. Puede ser que haya algunos métodos que requieran mucho tiempo, o un método que sea relativamente rápido pero que se llame mucho más a menudo de lo que se espera.
Es imposible saber si los cambios que realiza en un esfuerzo por acelerar las cosas realmente hacen una diferencia a menos que tenga algunos números para medir. Si puede demostrar que su código estaba gastando el 80% de su tiempo en una rutina y lo redujo al 35%, sabe que está progresando.
Entonces, rompe los instrumentos y comienza a medir. Si puede, es una buena idea medir mientras realiza cada una de las diferentes actividades que desea acelerar ... haga una sesión de creación de perfiles mientras se desplaza, una mientras selecciona tantas celdas diferentes como sea posible en un período fijo , etc. No olvides guardar los resultados para poder compararlos más tarde.
Reutilizar las células. La asignación de objetos tiene un costo de rendimiento, especialmente si la asignación tiene que ocurrir repetidamente durante un período corto, por ejemplo, cuando el usuario desplaza una vista de tabla. Si reutiliza las celdas en lugar de asignar nuevas, mejora considerablemente el rendimiento de la vista de tabla. Evitar la retransmisión de contenido. Cuando reutilice celdas con subvistas personalizadas, absténgase de presentar esas subvistas cada vez que la vista de tabla solicite una celda. Coloque las subvistas una vez, cuando se crea la celda. Utilice subvistas opacas. Al personalizar las celdas de vista de tabla, haga que las subvistas de la celda sean opacas, no transparentes.
Solo tenga en cuenta estos puntos ..
- ¿Está reutilizando las células? Lo que es una buena práctica hacer ...
- Asegúrese de no realizar cálculos costosos en la devolución de llamada cellForRowAtIndexPath, o en una función llamada desde CellForRowAtIndexPath.
- Usted dijo que hay una imagen de fondo. Otra razón por la que debes reutilizar tu celular.
here hay una buena información sobre la reutilización de células.
EDITAR: Encontré esta página muy tarde ..
Este hilo de preguntas de SO podría ayudarlo ... especialmente la respuesta aceptada ...