Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scrollToRowAtIndexPath with UITableView does not work

I have in iOS8 a table view like this:

tableView = UITableView(frame: view.bounds, style: .Plain)
view.addSubview(tableView)

When the user types and sends some text in the keyboard, the application ivoke the following method to scroll the tableView. The goal is to view the new text in the screen (like a chat)

let numberOfRows = tableView.numberOfRowsInSection(0)
        if numberOfRows > 0 {
            let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: 0)
            tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
        }

But the table view does not scroll to the bootom.

Someone has a solution?

Thank you.

Explanation:

Definition of the class:

class ChatViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextViewDelegate 

then I have the definition of the table view:

var tableView: UITableView! 

in viewDidLoad:

tableView = UITableView(frame: view.bounds, style: .Plain) 
tableView.dataSource = self 
tableView.delegate = self 
view.addSubview(tableView) 

then I have the call to the code that should make the scroll (second block of code on my answer). When I launch the application I expect the tableview to scroll down, but it does not work.

like image 746
Kobazzo Avatar asked Sep 11 '25 01:09

Kobazzo


2 Answers

The solution below worked for me. It's a combination of solutions found on StackOverflow. I called "scrollToRowAtIndexPath" after a very short delay.

func tableViewScrollToBottom(animated: Bool) {

    let delay = 0.1 * Double(NSEC_PER_SEC)
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

    dispatch_after(time, dispatch_get_main_queue(), {

        let numberOfSections = self.tableView.numberOfSections()
        let numberOfRows = self.tableView.numberOfRowsInSection(numberOfSections-1)

        if numberOfRows > 0 {
            let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
            self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
        }

    })
}

called by :

tableViewScrollToBottom(true)

Swift 3

func tableViewScrollToBottom(animated: Bool) {
    DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
        let numberOfSections = self.tableView.numberOfSections
        let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)

        if numberOfRows > 0 {
            let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
            self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: animated)
        }
    }
}
like image 189
Fox5150 Avatar answered Sep 12 '25 21:09

Fox5150


The solution at my problem is:

let numberOfSections = tableView.numberOfSections()
let numberOfRows = tableView.numberOfRowsInSection(numberOfSections-1)

if numberOfRows > 0 {
    println(numberOfSections)
    let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
    tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
like image 39
Kobazzo Avatar answered Sep 12 '25 20:09

Kobazzo