为什么不调用表视图委托方法?

时间:2019-09-23 03:43:06

标签: ios swift uitableview

我发现用 Release 配置构建的应用有时存在问题:tableView:heightForRowAt:委托方法未调用。

此问题与内部版本有关,对于某些内部版本,我总是会重现此问题,而对于其他一些内部版本,我永远都无法重现。

发生问题时,我可以看到tableView中的行的高度全部为44,而在tableView:heightForRowAt:方法中创建的断点从未被调用。

screenshots of normal and buggy result

在我的代码中,我尝试使用多态性以实现表视图数据源和委托方法的两种不同实现。这是一个简化的示例:

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    var tableController: BaseTableController!

    let vm = ViewModel(sections: [...])

    override func viewDidLoad() {
        super.viewDidLoad()

        tableController = VariantATableController(viewModel: vm)
        tableView.dataSource = tableController
        tableView.delegate = tableController
    }

}
class BaseTableController: NSObject, UITableViewDataSource, UITableViewDelegate {

    let viewModel: ViewModel

    init(viewModel: ViewModel) {
        self.viewModel = viewModel
        super.init()
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return viewModel.numberOfSections
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.sections[section].numberOfRows
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        fatalError("to be overridden")
    }    

}
class VariantATableController: BaseTableController {

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ACell", for: indexPath)
        let row = viewModel.sections[indexPath.section].rows[indexPath.row]
        cell.textLabel?.text = row.title
        cell.detailTextLabel?.text = row.detail
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 120
    }

}
class VariantBTableController: BaseTableController {
    ...
}

3 个答案:

答案 0 :(得分:0)

在调用委托和dataSource之前在viewDidLoad中添加以下行

tableView.rowHeight=UITableViewAutomaticDimension
tableView.estimatedRowHeight=120

并添加estimatedHeightForRowAt而不是heightForRowAt

 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

注意:要使用此功能,您需要为单元格正确设置自动布局。

答案 1 :(得分:0)

确保tableView:heightForRowAt:是在基类中定义的,而不仅仅是派生类。否则,它将在发行版本之外进行优化。

答案 2 :(得分:0)

tableView:heightForRowAt:放入class BaseTableController: NSObject, UITableViewDataSource, UITableViewDelegate {}

UITableViewDataSource, UITableViewDelegate是必需的。