¿Cómo desplazarse hasta el extremo exacto de UITableView?

Tengo una UITableView que se llena con celdas con altura dinámica. Me gustaría que la tabla se desplazara a la parte inferior cuando el controller de vista se empuja desde el controller de vista.

He intentado con contentOffset y tableView scrollToRowAtIndexPath pero todavía no estoy obteniendo la solución perfecta para exactamente lo que quiero.

¿Alguien puede ayudarme a solucionar este problema?

Aquí está mi código para desplazarme:

 let indexPath = NSIndexPath(forRow: commentArray.count-1, inSection: 0) tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true) 

Para Swift 3.0

Escribe una function:

 func scrollToBottom(){ DispatchQueue.global(qos: .background).async { let indexPath = IndexPath(row: self.yourArray.count-1, section: 0) self.tblComment.scrollToRow(at: indexPath, at: .bottom, animated: true) } } 

y llámelo después de volver a cargar los datos de la vista de tabla

 self.yourTable.reloadData() self.scrollToBottom() 

Cuando presiona el controller de vista que tiene la vista de tabla, debe desplazarse hasta la ruta de índice especificada solo después de que su vista de tabla haya terminado de cargarse.

 yourTableview.reloadData() dispatch_async(dispatch_get_main_queue(), { () -> Void in let indexPath = NSIndexPath(forRow: commentArray.count-1, inSection: 0) tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true) }) 

La razón para poner el método dentro de dispatch_async es que una vez que ejecuta reloadData, la siguiente línea se ejecutará inmediatamente y luego la recarga ocurrirá en el hilo principal. Entonces, para saber cuándo termina la tabla (Después de que todo cellforrowindex esté terminado), usamos GCD aquí. Básicamente no hay delegado en tableview, le dirá que la vista de tabla ha terminado de cargarse.

Esto funciona en Swift 3.0

 let pointsFromTop = CGPoint(x: 0, y: CGFloat.greatestFiniteMagnitude) tableView.setContentOffset(pointsFromTop, animated: true) 

Funciona en Swift 3+:

  self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.contentSize.height - UIScreen.main.bounds.height), animated: true) 

Si usó UINavigationBar con alguna altura y UITableView en UIView intente restar UINavigationBar altura de la altura de UITableView de UITableView . UITableView el punto top UINavigationBar mismo que el punto bottom UINavigationBar , de modo que esto afecte a los elementos bottom UITableView para desplazarse.

Swift 3

 simpleTableView.frame = CGRect.init(x: 0, y: navigationBarHeight, width: Int(view.frame.width), height: Int(view.frame.height)-navigationBarHeight) 

[Swift 3, iOS 10]

Terminé usando una solución tipo hacky, pero no depende de las filas indexpaths (que a veces provocan fallas), altura dinámica de celdas o evento de recarga de tablas, por lo que parece bastante universal y en la práctica funciona más confiable que otros que he encontrado

  • use KVO para rastrear el contenido de la tabla

  • evento de desplazamiento de fuego dentro del observador KVO

  • progtwigr la invocación de desplazamiento utilizando timer retardado para filtrar múltiples
    desencadenadores del observador

El código dentro de un ViewController:

 private var scrollTimer: Timer? private var ObserveContext: Int = 0 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) table.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.new, context: &ObserveContext) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) table.removeObserver(self, forKeyPath: "contentSize") } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if (context == &ObserveContext) { self.scheduleScrollToBottom() } } func scheduleScrollToBottom() { if (self.scrollTimer == nil) { self.scrollTimer = Timer(timeInterval: 0.5, repeats: false, block: { [weak self] (timer) in let table = self!.table let bottomOffset = table.contentSize.height - table.bounds.size.height if !table.isDragging && bottomOffset > 0 { let point: CGPoint = CGPoint(x: 0, y: bottomOffset) table.setContentOffset(point, animated: true) } timer.invalidate() self?.scrollTimer = nil }) self.scrollTimer?.fire() } }