iOS: 如何知道reloadData() 完成了它的任务?
iOS: How to know reloadData() was completed its task?
我想滚动到给定索引 (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)
}
任何帮助将不胜感激。
尝试这样做,它应该有效:
self.tblTimeEvent.reloadData()
DispatchQueue.main.async(execute: {
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
})
这将在主线程上执行 scrollToRow,这意味着在 reloadData 完成后(因为它在主线程上)
你可以做出一个非常可靠的假设,即当最后一次为屏幕上的可见部分调用 tableView(_:willDisplay:forRowAt:)
时,UITableView
已完成重新加载。
所以尝试这样的事情(对于第 0 部分中的行占用屏幕上可用 space 的 tableView):
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)
}
}
如 this answer 中所述,UITableView
的重新加载发生在下一个布局 运行 上(通常,当您 return 控制 运行 环形)。
因此,您可以使用主调度队列在下一个布局之后安排代码。你的情况:
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)
}
您可以使用...确保重新加载完成...
在 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")
}
希望这对某人有所帮助。干杯!
tableView.reloadData { [weak self] in
self?.doSomething()
}
您可以为此使用 CATransaction
CATransaction.begin()
CATransaction.setCompletionBlock {
// Completion
}
tableView.reloadData()
CATransaction.commit()
我想滚动到给定索引 (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)
}
任何帮助将不胜感激。
尝试这样做,它应该有效:
self.tblTimeEvent.reloadData()
DispatchQueue.main.async(execute: {
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
})
这将在主线程上执行 scrollToRow,这意味着在 reloadData 完成后(因为它在主线程上)
你可以做出一个非常可靠的假设,即当最后一次为屏幕上的可见部分调用 tableView(_:willDisplay:forRowAt:)
时,UITableView
已完成重新加载。
所以尝试这样的事情(对于第 0 部分中的行占用屏幕上可用 space 的 tableView):
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)
}
}
如 this answer 中所述,UITableView
的重新加载发生在下一个布局 运行 上(通常,当您 return 控制 运行 环形)。
因此,您可以使用主调度队列在下一个布局之后安排代码。你的情况:
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)
}
您可以使用...确保重新加载完成...
在 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")
}
希望这对某人有所帮助。干杯!
tableView.reloadData { [weak self] in
self?.doSomething()
}
您可以为此使用 CATransaction
CATransaction.begin()
CATransaction.setCompletionBlock {
// Completion
}
tableView.reloadData()
CATransaction.commit()