2017-04-26 72 views
4

我想滚动到给定索引(self.boldRowPath),但是当我调试scrollToRow之前执行reloadData()。如何知道reloadData已完成?如何知道reloadData()完成了他的任务?

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) 
} 

任何帮助将不胜感激。

+0

确保你看到(https://stackoverflow.com/questions/16071503 [如何辨别真假时的UITableView已完成ReloadData?] /如何对告诉-时-的UITableView,已完成的-reloaddata)。这是在Objective-C,但在那里提供的答案更完整... – Honey

+0

@Honey这是问8个月前,我没有找到这个链接bcoz没有标签为迅速,所以我没有达到这个链接扔谷歌 。 –

+0

了解,正是因为这个问题被标记为Swift ...是我没有把它标记为重复的原因:) – Honey

回答

6

尝试这样做,它应该工作:

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

这将执行scrollToRow在主线程,这意味着reloadData完成后(因为它是在主线程)

+0

感谢您的回答。它对我有帮助 –

+0

ummm。不应该在主线程上重新加载自己的所有时间?这不是一个UI更新?! – Honey

+0

当你调用reloadData()时,它会在主线程上重新加载自己,所以当它重新加载时你不能滚动tableview。你可以在主线程上调用它,以便在reloadData完成后立即开始排队。 @Honey –

1

你可以非常可靠地假设UITableView在上次调用屏幕上可见部分的时间tableView(_:willDisplay:forRowAt:)时重新加载。

所以尝试这样的事情(为的tableView其中部分0的行占用的可用空间在屏幕上):

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) 
    } 
} 
+0

这是每次都检查好吗?有没有别的办法? –

+0

tableview:willdisplay:forrowat:不会调用tableview中的所有项目,但只会在可见行上调用..所以如果tableview被向上滚动,这将不起作用... – deebee

2

this answer解释的,UITableView的重载发生在下一布局运行(通常,将控制权返回到运行循环时)。

因此,您可以使用主调度队列在下一个布局之后安排代码。在你的情况下:

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) 
     } 
    } 

你也可以通过手动呼叫layoutIfNeeded强制布局。但是这通常不是一个好主意(之前的选择是最好的):

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) 
    } 
相关问题