Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 425 Vote(s) - 3.56 Average
  • 1
  • 2
  • 3
  • 4
  • 5
scrollToRowAtIndexPath with UITableView does not work

#1
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.
Reply

#2
**Swift 5 Version**

extension UITableView {
func tableViewScrollToBottom(animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
let numberOfSections = self.numberOfSections
let index = self.numberOfRows(inSection: 0)
if index > 0 {
let indexPath = IndexPath(row: index-1, section: 0)
self.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.bottom, animated: animated)
}
}
}
}

**You can use like:**

[YOUR_TABLE_VIEW].tableViewScrollToBottom(animated: [TRUE])
Reply

#3
I go the same problem in late 2020.

Since i really did not want some magic dispatch-timeout, i played around a bit. What helped (and was not mentioned here before) was a forced layout for the UITableView:

_viewTable.layoutIfNeeded()
_viewTable.scrollToRow(at:IndexPath(row:index, section:0), at:.middle, animated:false)
Reply

#4
Try below:

```
if tableView.numberOfRows(inSection: 0) > 0 {
tableView.scrollToRow(at: IndexPath(row: ROW, section: SECTION), at: .top, animated: false)
}
```
Reply

#5
I solved the issue by calling `scrollToRow()` in the `viewWillLayoutSubviews()
Reply

#6
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.


Reply

#7
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.
Reply

#8
// 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)
Reply

#9
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.
Reply

#10
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)
}
}
}
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through