Uitableview Scrolls to Top on Reload

UITableview Scrolls to Top on Reload

Igor's answer is correct if you are using dynamically resizable cells (UITableViewAutomaticDimension)

Here it is in swift 3:

    private var cellHeights: [IndexPath: CGFloat?] = [:]
var expandedIndexPaths: [IndexPath] = []

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cellHeights[indexPath] = cell.frame.height
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let height = cellHeights[indexPath] {
return height ?? UITableViewAutomaticDimension
}
return UITableViewAutomaticDimension
}


func expandCell(cell: UITableViewCell) {
if let indexPath = tableView.indexPath(for: cell) {
if !expandedIndexPaths.contains(indexPath) {
expandedIndexPaths.append(indexPath)
cellHeights[indexPath] = nil
tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
//tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
}
}

iOS TableView reload and scroll top

UItableView method scrollToRow(at:at:animated:) Scrolls through the table view until a row identified by index path is at a particular location on the screen.

Use

tableView.scroll(to: .top, animated: true)

You can use my extension

extension UITableView {

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

func scroll(to: scrollsTo, animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
let numberOfSections = self.numberOfSections
let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
switch to{
case .top:
if numberOfRows > 0 {
let indexPath = IndexPath(row: 0, section: 0)
self.scrollToRow(at: indexPath, at: .top, animated: animated)
}
break
case .bottom:
if numberOfRows > 0 {
let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
self.scrollToRow(at: indexPath, at: .bottom, animated: animated)
}
break
}
}
}

enum scrollsTo {
case top,bottom
}
}

How can I reload UITableView when I scroll to the top with current scroll position? (like chat apps)

Swift 3

This post is a bit old, but here a solution:

1) Detect when you are scrolling near to the top in scrollViewDidScroll,

2) Load the new messages

3) Save the contentSize, reload the tableView

4) Set the contentOffset.y of the tableView to (newContentSizeHeight - oldContentSizeHeight) which is exactly the current point

and here the code:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == tableView {
if tableView.contentOffset.y < 50 {
loadMessages()
let oldContentSizeHeight = tableView.contentSize.height
tableView.reloadData()
let newContentSizeHeight = tableView.contentSize.height
tableView.contentOffset = CGPoint(x:tableView.contentOffset.x,y:newContentSizeHeight - oldContentSizeHeight)
}
}
}

How to get a UITableview to go to the top of page on reload?

Here's another way you could do it:

Objective-C

[tableView setContentOffset:CGPointZero animated:YES];

Swift 3 and higher

tableView.setContentOffset(.zero, animated: true)

Probably the easiest and most straight forward way to do it.

UITableView scrolls to top when reloading cells with changing cell heights

Always update the UI on the main thread. So just place

[self.tableView reloadData];

inside a main thread:

dispatch_async(dispatch_get_main_queue(), ^{
//UI Updating code here.
[self.tableView reloadData];
});


Related Topics



Leave a reply



Submit