tutorial started getting iphone objective-c ios ipad

iphone - started - Cómo detectar que la animación ha finalizado en UITableView beginUpdates/endUpdates?



ios getting started (6)

¿Qué hay de esto?

[CATransaction begin]; [CATransaction setCompletionBlock:^{ // animation has finished }]; [tableView beginUpdates]; // do some work [tableView endUpdates]; [CATransaction commit];

Esto funciona porque las animaciones CALayer usan animaciones CALayer internamente. Es decir, agregan las animaciones a cualquier CATransaction abierta. Si no existe una CATransaction abierta (el caso normal), entonces una comienza implícitamente, que finaliza al final del recorrido actual. Pero si comienzas uno tú mismo, como se hace aquí, entonces usará ese.

Estoy insertando / eliminando celda de tabla usando insertRowsAtIndexPaths/deleteRowsAtIndexPaths envuelto en beginUpdates/endUpdates . También estoy usando beginUpdates/endUpdates al ajustar rowHeight. Todas estas operaciones están animadas por defecto.

¿Cómo puedo detectar que la animación ha finalizado al usar beginUpdates/endUpdates ?


Aún no he encontrado una buena solución (a falta de subclasificar UITableView). Decidí usar performSelector:withObject:afterDelay: por ahora. No es ideal, pero hace el trabajo.

ACTUALIZACIÓN : parece que puedo usar scrollViewDidEndScrollingAnimation: para este propósito (esto es específico para mi implementación, ver comentario).


Puede encerrar su (s) operación (es) en el bloque de animación UIView así:

- (void)tableView:(UITableView *)tableView performOperation:(void(^)())operation completion:(void(^)(BOOL finished))completion { [UIView animateWithDuration:0.0 animations:^{ [tableView beginUpdates]; if (operation) operation(); [tableView endUpdates]; } completion:^(BOOL finished) { if (completion) completion(finished); }]; }

Créditos a https://.com/a/12905114/634940 .


Puede usar tableView:willDisplayCell:forRowAtIndexPath: como:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"tableView willDisplay Cell"); cell.backgroundColor = [UIColor colorWithWhite:((indexPath.row % 2) ? 0.25 : 0) alpha:0.70]; }

Pero también se llamará cuando una celda que ya se encuentra en la tabla se mueva de la pantalla a la pantalla, por lo que puede no ser exactamente lo que está buscando. Simplemente miré a través de todos los métodos delegados UITableView y UIScrollView y no parece haber nada que manejar justo después de insertar una celda de animación.

¿Por qué no simplemente llamar al método que desea que se llame cuando la animación termina después de la endUpdates ?

- (void)setDownloadedImage:(NSMutableDictionary *)d { NSIndexPath *indexPath = (NSIndexPath *)[d objectForKey:@"IndexPath"]; [indexPathDelayed addObject:indexPath]; if (!([table isDragging] || [table isDecelerating])) { [table beginUpdates]; [table insertRowsAtIndexPaths:indexPathDelayed withRowAnimation:UITableViewRowAnimationFade]; [table endUpdates]; // --> Call Method Here <-- loadingView.hidden = YES; [indexPathDelayed removeAllObjects]; } }


Una posible solución podría ser heredar de UITableView en el que llama a endUpdates y sobrescribir su setContentSizeMethod , ya que UITableView ajusta su tamaño de contenido para que coincida con las filas añadidas o eliminadas. Este enfoque también debería funcionar para reloadData .

Para asegurarse de que se envíe una notificación solo después de endUpdates , también podría sobrescribir endUpdates y establecer una endUpdates allí.

// somewhere in header @private BOOL endUpdatesWasCalled_; ------------------- // in implementation file - (void)endUpdates { [super endUpdates]; endUpdatesWasCalled_ = YES; } - (void)setContentSize:(CGSize)contentSize { [super setContentSize:contentSize]; if (endUpdatesWasCalled_) { [self notifyEndUpdatesFinished]; endUpdatesWasCalled_ = NO; } }


Versión Swift

CATransaction.begin() CATransaction.setCompletionBlock({ do.something() }) tableView.beginUpdates() tableView.endUpdates() CATransaction.commit()