scrollToRowAtIndexPath with UITableView does not w

2019-01-21 11:16发布

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.

13条回答
手持菜刀,她持情操
2楼-- · 2019-01-21 11:49
// First figure out how many sections there are
 let lastSectionIndex = self.tblTableView!.numberOfSections() - 1

// Then grab the number of rows in the last section

let lastRowIndex = 
self.tblTableView!.numberOfRowsInSection(lastSectionIndex) - 1

// Now just construct the index path

let pathToLastRow = NSIndexPath(forRow: lastRowIndex, inSection: lastSectionIndex)

// Make the last row visible
self.tblTableView?.scrollToRowAtIndexPath(pathToLastRow, atScrollPosition: UITableViewScrollPosition.None, animated: true)
查看更多
来,给爷笑一个
3楼-- · 2019-01-21 11:49

All above codes are fine, but in my case when I want to load the tableView as well as scroll to bottom of the tableView instantly when the controller loads, for that situation above methods are taking some time to scroll to the bottom of the tableView. So I have followed these codes.

Override tableView reload as

extension UITableView
{
    func reloadData(completion: @escaping ()->()) {
        UIView.animate(withDuration: 0, animations: { self.reloadData() })
        { _ in completion() }
    }
}

Written scroll to bottom method as follows:

func tableViewScrollToBottom
{
     if self.tblChat.contentSize.height > self.tblChat.frame.size.height
     {
         let offset:CGPoint = CGPoint(x: 0,y :self.tblChat.contentSize.height-self.tblChat.frame.size.height)
         self.tblChat.setContentOffset(offset, animated: false)
     }
 }

and then reload tableView when data loads completes from web service or from any core data entity:

tblChat.reloadData()
{
     self.tableViewScrollToBottom
}

Now its working smooth as I wanted.

查看更多
该账号已被封号
4楼-- · 2019-01-21 11:53

I know this is an older thread, but it's still relevant. Instead of dealing with timeouts that could sometimes fail to be well timed, use synchronous blocks on the main thread (normally not something I'd do, but we're talking milliseconds):

DispatchQueue.main.sync {
  // Reload code goes here...
  tableView.reloadData()
}

DispatchQueue.main.sync {
  // Row, section and other checks / initialization go here...
  tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}

This always works for me.

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-01-21 11:54

It's simple. Just do the scroll operation in viewDidLayoutSubViews()

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.scrollToBottom(animated: false)
}

fileprivate func scrollToBottom(animated: Bool) {
    if self.items.count > 0 {
        let lastIndex = IndexPath(row: items.count - 1, section: 1)
        self.tableView.scrollToRow(at: lastIndex, at: .bottom, animated: animated)
    }
}

It seems like tableview could get the correct positon after layout subviews.

查看更多
虎瘦雄心在
6楼-- · 2019-01-21 11:55

I have the problem with a bigger index say even 15. Only indexes till 5-6 use to work. By making "animated: false" scrollToRowAtIndexPath() worked perfectly.

查看更多
手持菜刀,她持情操
7楼-- · 2019-01-21 11:57

If the keyboard is still visible you have to set the UITableView's contentInset property to compensate for the keyboard height at the bottom of the screen. Otherwise your cell might be hidden behind the keyboard because the UITableView doesn't know that half of its content is hidden by it.

Or use a UITableViewController which handles that automatically.

查看更多
登录 后发表回答