什么时候调用CellForRowAt? -排队直到VC排在最前面?

时间:2019-05-09 21:13:57

标签: swift uitableview

我有两个视图控制器A和B。

A有一个表格视图。

A被包装在导航控制器中,该控制器可以将其推入B。B具有调用tableView.reloadData()的处理程序。但是,在B弹出并且A再次可见之前,不会在A中调用cellForRowAt方法。

是否存在仅在VC是最顶部的视图控制器时调用“ cellForRowAt”的正式文档?这是理想的结果,我想确保这是可能发生的。

-- denotes action
// denotes current VC
console denotes print message

//AVC:
--push to BVC
//BVC:
--press handler Button
console: "handling"
console: "nil"
console: "numberOfRowsInSection"
--press back navigation
console: "Disappearing"
//AVC:
console: "CellForROwAt"

要复制的文件的依据

https://gist.github.com/MochaTheCoder/628af8950f39e5fc0896cc12d77c6fb2

-代码-

class AViewController: UIViewController {

    @objc private func pushBVC() {
        let bVC = BViewController()
        bVC.handler = {
            print("handling")
            print(self.view.window)
            self.tableView.reloadData()
        }
        navigationController?.pushViewController(bVC, animated: true)
    }

}

extension AViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("numberOfRowsInSection")
        return 1
}
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("CellForROwAt")
        return UITableViewCell()
    }
}

----

class BViewController: UIViewController {

    var handler: (() -> Void) = {}

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        print("Disappearing")
    }

    @objc private func doHandler() {
        handler()
    }

}

2 个答案:

答案 0 :(得分:1)

当按下第二个视图控制器时,第一个视图控制器实际上已从窗口中删除。因此,在您调用reloadData时,表视图不在窗口层次结构中,因此此时它不会自动更新。

在关闭第二个视图控制器并再次显示第一个视图控制器的过程中,将其重新添加到窗口层次结构(以及表视图)中,并且表视图使用此事件通过挂起的事件刷新自身更新。

这就是为什么直到收到cellForRowAt消息后才看到对print("Disappearing")的呼叫的原因。

因此,不是在不可见的情况下表不会更新,在不属于窗口层次结构的表时也不会更新。

答案 1 :(得分:0)

每次cellForRowAt需要显示特定UITableView的单元格时,都会调用IndexPath函数,这是否是因为父项ViewController刚刚被加载并该表将要显示,或者因为用户正在滚动tableView并且新的单元格需要变得可见。

请记住,单元格本身是可重用的。当IndexPath不再可见时,该单元格将被回收并重新用于即将滚动到屏幕上的IndexPath。当tableView滚动回到先前查看的IndexPath时,将再次为该IndexPath调用cellForRowAt,并使用正确类型的新出队单元格。

所有这些仅应在tableView可见时发生。它不必是最顶层的ViewController。在前景为模态的iPad上,tableView仍可在后台滚动,并且cellForRowAt仍会根据需要调用。即使在iPhone上,顶部带有alertView,也可能发生。只要显示了tableView,并且需要进入一个新的单元格IndexPath,就会调用cellForRowAt。对于大多数iPhone屏幕情况,使用标准ViewControllers,通常只会在最顶部的ViewController上发生。