2011-08-21 20 views
7

Tengo un UITableView con contenido de imágenes pesadas. Entonces el desplazamiento ya no es fluido. Quiero agregar un temporizador para cargar las imágenes, mientras se desplaza creo el temporizador para cada fila. Si la celda sale de la vista, cancelo el temporizador. Si no, me desvanezco en las imágenes.UITableView cell simplemente desapareció la devolución de llamada?

Mi pregunta es: ¿hay una devolución de llamada para que una celda salga de la vista? Estoy leyendo el documento, pero no estoy seguro de que haya algo para mis necesidades.

¡Gracias por la ayuda!

EDIT: El código que estoy usando (esta es la biblioteca three20, estoy usando una TTTableItemCell personalizada. El "_tabBar1.tabItems = item.photos" es los recursos de hoging de línea. En la primera carga está bien porque las fotos se cargan de forma asíncrona desde el servidor, pero cuando me desplazo hacia atrás o volver a cargar la vista, todos ellos están cargados de forma sincrónica, y el desplazamiento no es suave más, especialmente en un iPhone 3G:.

- (void)setObject:(id)object { 
    if (_item != object) { 
     [super setObject:object]; 

     Mission* item = object; 

     self.textLabel.text = item.name; 
     _tabBar1.tabItems = nil; 

     timerFeats = [NSTimer scheduledTimerWithTimeInterval:(0.5f) target:self selector:@selector(updateFeats) userInfo:nil repeats: NO]; 
     //_tabBar1.tabItems = item.photos; 
    } 
} 

-(void)updateFeats { 
    DLog(@"timer ended"); 
    Mission* item = self.object; 
    self._tabBar1.tabItems = item.photos; 
} 

Respuesta

5

Muy bien, encontré la manera.

En realidad, hay una devolución de llamada para saber qué celda está a punto de perderse de vista. :

- (void)willMoveToSuperview:(UIView *)newSuperview; 

Así que mi código es:

- (void)willMoveToSuperview:(UIView *)newSuperview { 
    [super willMoveToSuperview:newSuperview]; 
    if(!newSuperview) { 
     DLog(@"timer invalidated"); 
     if ([timerFeats isValid]) { 
      [timerFeats invalidate]; 
     } 

    } 
} 

Si no hay newSuperview la célula se va fuera de la vista y por lo que compruebe primero que mi cronómetro no ha sido invalidada, sin embargo, y luego Lo cancelo

+1

Esto parece disparar en cuanto una celda viene * en * para ver – Matthew

+1

@Matt a partir de iOS 7.02, este método podría no llamarse en absoluto cuando se desplaza hacia afuera de una celda y lo vuelve a desplazar hacia adentro. Pero como pronto en que se vuelva a ver, se llama al método prepareForReuse. Durante el tiempo en que no es visible, solo la bandera oculta es VERDADERO, pero aún está adjunta a la vista de tabla. Entonces no hay cambio en la supervista. – Klaas

0

cuando primero se muestra un UITableView llama a este método una vez para cada fila

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath 

Después de esto, se llama al método siempre que se requiera una nueva fila, que a menudo es el resultado del desplazamiento para revelar una nueva fila y sacar una vista anterior del otro extremo.

Este es un gancho ideal para saber qué filas son visibles. Para comprobar que las células son visibles puede llamar

- (NSArray *)indexPathsForVisibleRows 

Debido a que el tableview es el único que mantiene una referencia a las células antes de ser reciclados o recién creaetd no se puede tener una idea de los temporizadores. Lo que sugiero es la creación de una Ivar NSMutableDictionary y cuando crea sus células poner el temporizador a la NSMutableDictionary

[timersForIndexs setObject:yourTimer forKey:indexPath]; 

Ahora, cuando usted reciba - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath que hay que hacer algo como

NSMutableDictionary *tmpDictionary = [timersForIndexs copy]; 

[tmpDictionary removeObjectsForKeys:[self.tableView indexPathsForVisibleRows]]; 

NSArray *timers = [tmpDictionary allKeys]; 

[timers makeObjectsPerformSelector:@selector(invalidate)]; 

no estoy en al frente de xcode, así que esto está codificado en seco, por favor avíseme si tiene algún problema

+0

Lo intento, pero aparentemente, si utilizo [tableView cellForRowAtIndexPath: indexToRemove] en una celda que no es visible obtengo un nulo, por lo que no puedo cancelar mi temporizador. – rnaud

+0

He actualizado mi respuesta –

+0

Obtengo la matriz de las filas visibles, el problema es que solo puedo acceder a estas filas con el método cellForRowAtIndexPath. Cualquier otra fila me da un (nulo). Supongo que es porque la célula ha sido quitada de la cola. – rnaud

1

Es mejor utilizar un enfoque KVO:

En su método awakeFromNib (o cualquier otro método que se utiliza para crear una instancia de la célula) añadir los siguientes:

- (void)awakeFromNib { 
    [self addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew context:nil]; 

    ... 
} 

Asegúrese de poner en práctica el método delegado de el observador de la siguiente manera:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if([keyPath isEqualToString:@"hidden"]) { 
     NSLog(@"cell is hidden"); 
    } 
} 
+0

Esto no funciona para mí. Solo me notifican cuando la celda se vuelve visible de nuevo. El KVO no se activa cuando el sistema se oculta a VERDADERO. También traté de reemplazar a setHidden:, pero tampoco se llama cuando se realiza la transición a hidden = TRUE; – Klaas

8

Si utilizas iOS 6 en adelante, simplemente reemplazar este método:

- tableView:didEndDisplayingCell:forRowAtIndexPath:

Se llamará cuando la celda ya se haya salido de la vista, y la obtendrá junto con su indexPath.

Cuestiones relacionadas