ios objective-c uitableview uiscrollviewdelegate

ios - ¿Quieres que UITableView se ajuste a la celda?



objective-c uiscrollviewdelegate (7)

¡Hay un método de delegado UIScrollView especialmente para esto!

La vista de la tabla (que es una vista de desplazamiento) llamará - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset cuando el usuario deja de desplazarse. Puedes configurar manipular el targetContentOffset para asegurarte de que termine donde quieres, y desacelerará el final en esa posición (como un UIScrollView de paginación).

Por ejemplo, si tus celdas tuvieran 100 puntos de altura, podrías hacer:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { targetContentOffset->y = 100 * (int)targetContentOffset->y/100; }

Por supuesto, también puede inspeccionar el targetContentOffset pasado para ver dónde iba a aterrizar, y luego encontrar la celda en la que se encuentra y modificarla de manera apropiada.

Estoy mostrando imágenes bastante grandes en un UITableView . A medida que el usuario se desplaza, me gustaría que la vista de tabla siempre tome la foto más central en el centro. Es decir, cuando la tabla está en estado de reposo, siempre tendrá una UITableViewCell al centro.

¿Cómo se hace esto?


Construyendo a partir de lo que @jszumski publicó, si desea que el snap ocurra a medio arrastrar, use este código:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { [self centerTable]; } - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { [self centerTable]; } - (void)centerTable { NSIndexPath *pathForCenterCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), CGRectGetMidY(self.tableView.bounds))]; [self.tableView scrollToRowAtIndexPath:pathForCenterCell atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; }


Extendiendo la respuesta de @ jesse-rusak anterior, este es el código que necesitaría agregar a su subclase UITableViewController si tiene celdas con alturas variables. Esto evitará el problema de doble desplazamiento en la respuesta aceptada.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { NSIndexPath *pathForTargetTopCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), targetContentOffset->y)]; targetContentOffset->y = [self.tableView rectForRowAtIndexPath:pathForTargetTopCell].origin.y; }


Extendiendo la respuesta de @mikepj, (que a su vez extendió la gran respuesta de @JesseRusak), este código le permite conectarse a una celda, incluso cuando las celdas tienen una altura variable (o desconocida), y se ajustará a la siguiente fila si desplácese sobre la mitad inferior de la fila, haciéndola más "natural".

Código Swift 4.2 original: (por conveniencia, este es el código real que desarrollé y probé)

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { guard var scrollingToIP = table.indexPathForRow(at: CGPoint(x: 0, y: targetContentOffset.pointee.y)) else { return } var scrollingToRect = table.rectForRow(at: scrollingToIP) let roundingRow = Int(((targetContentOffset.pointee.y - scrollingToRect.origin.y) / scrollingToRect.size.height).rounded()) scrollingToIP.row += roundingRow scrollingToRect = table.rectForRow(at: scrollingToIP) targetContentOffset.pointee.y = scrollingToRect.origin.y }

(traducido) Código Objective-C: (ya que esta pregunta está etiquetada objective-c )

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { NSIndexPath *scrollingToIP = [self.tableView indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)]; if (scrollingToIP == nil) return; CGRect scrollingToRect = [table rectForRowAtIndexPath:scrollingToIP]; NSInteger roundingRow = (NSInteger)(round(targetContentOffset->y - scrollingToRect.origin.y) / scrollingToRect.size.height)); scrollingToIP.row += roundingRow; scrollingToRect = [table rectForRowAtIndexPath:scrollingToIP]; targetContentOffset->y = scrollingToRect.origin.y; }


Puede usar los métodos UIScrollViewDelegate en UITableView para hacer esto:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { // if decelerating, let scrollViewDidEndDecelerating: handle it if (decelerate == NO) { [self centerTable]; } } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [self centerTable]; } - (void)centerTable { NSIndexPath *pathForCenterCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), CGRectGetMidY(self.tableView.bounds))]; [self.tableView scrollToRowAtIndexPath:pathForCenterCell atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; }


UITableView extiende UIScrollView ...

myTableView.pagingEnabled = YES


para los rápidos

override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate == false { self.centerTable() } } override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { self.centerTable() } func centerTable() { let midX:CGFloat = self.tableView.bounds.midX let midY:CGFloat = self.tableView.bounds.midY let midPoint:CGPoint = CGPoint(x: midX, y: midY) if let pathForCenterCell:IndexPath = self.tableView .indexPathForRow(at: midPoint) { self.tableView.scrollToRow(at: pathForCenterCell, at: .middle, animated: true) } }//eom