2017-04-26 70 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) 
    } 
相關問題