Mostrar cronómetro StopWatch en UITableViewCell dinámicamente

Quiero mantener los valores del timer y UITableViewCell desde el inicio en un nuevo UITableViewCell pero mi problema es que puedo mostrar con éxito el cronómetro en la primera celda, pero cuando bash agregar una nueva celda en UITableView mi timer se establece en la segunda celda y no puedo definir cómo mantener vivo mi primer timer.

Pensé en administrar un Array, pero quiero llamar a recargar TableData cada vez, pero creo que eso es malo 🙁

Intenté solucionar el problema como se muestra a continuación, pero no estoy pensando cómo mostrar TimerValue en la celda anterior con el cronómetro de trabajo dynamic del mismo conteo y la nueva celda timerValue desde el inicio.

Una solución estática, pero mis filas se están insertando dinámicamente y también se eliminan de TableView, por lo que la solución estática me limita al recuento específico de filas y busca una solución dinámica.

  - (void) putDelayOnTimeOut { if (!_timerQueue) { _timerQueue = dispatch_queue_create("timer_queue", NULL); } dispatch_async(_timerQueue, ^{ self.startTime = [NSDate date]; if (globalRowIndex == 0) { _timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(showTimeoutActivity:) userInfo:nil repeats:YES]; } else if (globalRowIndex == 1) { _timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(showTimeoutActivity1:) userInfo:nil repeats:YES]; } //[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; //[[NSRunLoop currentRunLoop] run]; [_timer fire]; }); } - (void)showTimeoutActivity:(id)unused { if( [_timer isValid] ) { NSTimeInterval interval = [self.startTime timeIntervalSinceNow]; interval = (-1 * interval); NSString *timerString = [self formatInterval:interval]; NSLog(@"%@", timerString); MyCell *cell = (MyCell *)[self.activeCallTbl viewWithTag:globalRowIndex+10]; //NSIndexPath *indexPath = [self.activeCallTbl indexPathForCell:cell]; //NSLog(@"%d",indexPath.row); cell.timerLbl.text = timerString; } } - (void)showTimeoutActivity1:(id)unused { if( [_timer isValid] ) { NSTimeInterval interval = [self.startTime timeIntervalSinceNow]; interval = (-1 * interval); NSString *timerString = [self formatInterval:interval]; NSLog(@"%@", timerString); MyCell *cell = (MyCell *)[self.activeCallTbl viewWithTag:globalRowIndex+10]; //NSIndexPath *indexPath = [self.activeCallTbl indexPathForCell:cell]; //NSLog(@"%d",indexPath.row); cell.timerLbl.text = timerString; } } 

No estoy seguro de haber comprendido exactamente lo que estás pidiendo … pero lo bash.

Una solución simple puede ser subclasificar su UITableViewCell y agregar el timer a la propia celda. Por lo tanto, la celda tendrá la reference al timer y creará una nueva cada vez que se agregue una nueva celda a TableView

Adjunto un código de ejemplo: Enlace (He agregado 3 celdas estáticamente, pero puedes agregarlas como quieras, simplemente presiona una celda para iniciar el cronómetro, si tocas nuevamente, el cronómetro comenzará de nuevo desde 0)

Cree su subclass celular personalizada y agregue algunos methods como estos:

 - (void) startTimer { // invalidate a previous timer in case of reuse if (self.timer) [self.timer invalidate]; self.startTime = [NSDate date]; // create a new timer self.timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(calculateTimer) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; [self.timer fire]; } - (void)calculateTimer { NSTimeInterval interval = [self.startTime timeIntervalSinceNow]; interval = (-1 * interval); NSString *intervalString = [NSString stringWithFormat:@"%f", interval]; self.timerLabel.text = intervalString; } 

Luego, en la implementación UITableViewController, simplemente llame

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { TimerCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; [cell startTimer]; } 

Para más detalles pregunte o vea el proyecto adjunto.

Esta es la forma más rápida que he encontrado, aunque alguien preferiría dejar el código del timer y la reference dentro del controller de vista de tabla (pero necesitará más código)

EDITAR

Tal como está escrito en el comentario de Spynet, esto no funcionará si tiene más de 7/8 celdas (la cantidad de celdas que pueden ajustarse a la pantalla), ya que cuando se desplaza, las celdas UITableView se reutilizan. Por lo tanto, se utilizará una única celda en diferentes routes de índice, por lo que iniciar un timer en la primera celda, luego desplazarse, hará que vea el timer que ya se inició cada 7/8 celdas (porque es el cronómetro de la celda creada anteriormente)

Para resolver esto hay muchas forms. Uno podría ser eliminar el timer de la celda y crear una matriz de timeres en el ViewController. Un timer para cada ruta de índice. Otra forma (pero no lo recomiendo si las celdas son muchas) es no reutilizar las celdas.

A partir de mi proyecto de ejemplo:
1: cree un file de nib (llámelo TimerCell.xib) y copie / pegue el prototipo de célula dentro de él desde el guión gráfico
2: agregue esta propiedad a TimerViewController

 @interface TimerViewController () @property (strong, nonatomic) NSMutableArray *cells; @end 

3 – en el método initWithCoder inicialice la matriz:

 - (id)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { _cells = [NSMutableArray array]; } return self; } 

4: actualice el método cellForRowAtIndexPath y cámbielo de la siguiente manera:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { TimerCell *cell = nil; if ([self.cells count] > indexPath.row) { cell = [self.cells objectAtIndex:indexPath.row]; } else { cell = [[[NSBundle mainBundle] loadNibNamed:@"TimerCell" owner:self options:nil] objectAtIndex:0]; [self.cells addObject:cell]; } // Configure the cell... return cell; } 

De esta forma, las celdas no se reutilizarán.