怎么知道reloadData()完成了他的任务?

时间:2017-04-26 12:20:38

标签: ios swift uitableview reloaddata

我想滚动到给定的索引(self.boldRowPath),但是当我在scrollToRow之前执行调试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)
 }

非常感谢任何帮助。

6 个答案:

答案 0 :(得分:17)

尝试这样做,它应该有效:

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

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

答案 1 :(得分:5)

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

答案 2 :(得分: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)
  }
}

答案 3 :(得分:1)

您可以确保使用...完成重新加载...

在Swift 3.0 + 中,我们可以为UITableView创建扩展名,如下所示:escaped Closure

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

并在需要的地方像下面一样使用它:

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

希望这对某人有帮助。欢呼!

答案 4 :(得分:0)

tableView.reloadData { [weak self] in
    self?.doSomething()
}

答案 5 :(得分:0)

您可以为此使用 CATransaction

CATransaction.begin()
CATransaction.setCompletionBlock {
    // Completion
}
tableView.reloadData()
CATransaction.commit()