iOS: How do I know that reloadData () has completed its task?

I want to scroll to the given index ( self.boldRowPath ), but when I debug scrollToRow , it runs until reloadData() .

How to find out that reloadData complete?

 func getAllTimeEvent() { self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo) self.tblTimeEvent.reloadData() self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true) } 

Any help would be greatly appreciated.

+9
source share
5 answers

Try this, it should work:

 self.tblTimeEvent.reloadData() DispatchQueue.main.async(execute: { self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true) }) 

This will launch scrollToRow in the main thread, which means that after reloadData is executed (because it is in the main thread)

+17
source

As explained in this answer , reloading the UITableView occurs the next time the layout starts (usually when you return control to the launch loop).

So, you can schedule your code after the next layout using the main send queue. In your case:

  func getAllTimeEvent() { self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo) self.tblTimeEvent.reloadData() DispatchQueue.main.async { self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true) } } 

You can also force the layout by manually calling layoutIfNeeded . But this is usually not a good idea (the previous option is the best):

  func getAllTimeEvent() { self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo) self.tblTimeEvent.reloadData() self.tblTimeEvent.layoutIfNeeded() self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true) } 
+5
source

You can make a pretty firm assumption that the UITableView is rebooting when the last time tableView(_:willDisplay:forRowAt:) is called for visible sections on the screen.

So, try something like this (for tableView, where the rows in section 0 take up free space on the screen):

 override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { let lastRowIndex = tableView.numberOfRows(inSection: 0) if indexPath.row == lastRowIndex - 1 { // tableView done reloading self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true) } } 
+1
source

you can verify that the reboot is done using ...

In Swift escaped Closure we can create an extension for UITableView with escaped Closure as escaped Closure below:

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

And use it as below where you want:

 Your_Table_View.reloadData { print("reload done") } 

I hope this helps someone. Hooray!

+1
source
 tableView.reloadData { [weak self] in self?.doSomething() } 
0
source

Source: https://habr.com/ru/post/1267181/


All Articles