【问题标题】:Nested UITableViewDataSource doesn't call cellForRowAt:嵌套的 UITableViewDataSource 不调用 cellForRowAt:
【发布时间】:2019-09-13 07:39:50
【问题描述】:

我正在尝试在其每个单元格中包含另一个 UITableView(次要)的 UITableView(主要)。主要和次要表视图具有自己的数据源对象类,并且 MajorDatasource 对象包含 MinorDatasource 对象的数组,如下所示。

我在每个类的UITableViewDatasource 函数中设置了断点,看起来MinorDatasourcetableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) 函数从未被调用过,即使labels 数组包含对象。

我知道 UITableViewdatasource 属性很弱,因此需要在某处对其进行强引用,但是,我认为在这种情况下这是正确的,我在这里做错了什么吗?

class MajorDatasource: NSObject, UITableViewDataSource {
    var minorDatasources:[MinorDatasource]

    init(minorDatasources:[MinorDatasource]) {
        self.minorDatasources = minorDatasources
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return minorDatasources.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MajorTableViewCell")! as! MajorTableViewCell
        cell.tableView.dataSource = minorDatasources[indexPath.row]
        return cell
    }
}

class MinorDatasource: NSObject, UITableViewDataSource {
    var labels:[String]

    init(labels:[String]) {
        self. labels = labels
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return labels.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MinorTableViewCell")!
        cell.textLabel?.text = labels[indexPath.row]
        return cell
    }
}

【问题讨论】:

  • 所以你的意思是说'MinorDatasource'中的tableview dataSource方法没有被调用?
  • @nikBhosale numberOfRowsInSection 被调用(并返回,比如 2),但 cellForRowAt 没有被调用。
  • 如果 numberOfRows 返回一些值,因为它们都是数据源方法,则不应发生这种情况。只有当 numberOfRows 返回 '0' 时才可能调用 numberOfRows 而不是 cellForRow
  • @nikBhosale 如果数据源由于某种原因被释放,则可能会发生这种情况,但是,我不确定为什么会出现这种情况,因为数据源是 minorDatasources 数组。
  • 那么它会是“dequeueReusableCell”单元格吗?

标签: swift uitableview datasource


【解决方案1】:

您还没有展示您的其余代码 - 单元类、控制器类等 - 所以很难说出您可能遗漏了什么或做错了什么。

因此,根据您包含的代码和您的描述,这里有一个工作示例,应该非常接近您的目标。

结果:

全部通过代码,所以没有@IBOutlets 之类的......只需创建一个新的UIViewController 并将其类指定为MajorMinorViewController

//
//  MajorMinorViewController.swift
//
//  Created by Don Mag on 9/13/19.
//

import UIKit

class MajorTableViewCell: UITableViewCell {

    var tableView: UITableView = {
        let v = UITableView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() -> Void {

        contentView.backgroundColor = .yellow

        contentView.addSubview(tableView)

        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor, constant: 0.0),
            tableView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor, constant: 0.0),
            tableView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor, constant: 0.0),
            tableView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor, constant: 0.0),

            tableView.heightAnchor.constraint(equalToConstant: 205.0),
            ])

        tableView.register(MinorTableViewCell.self, forCellReuseIdentifier: "MinorTableViewCell")

    }
}

class MinorTableViewCell: UITableViewCell {
    // default UITableViewCell
}

class MajorDatasource: NSObject, UITableViewDataSource {
    var minorDatasources:[MinorDatasource]

    init(minorDatasources:[MinorDatasource]) {
        self.minorDatasources = minorDatasources
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return minorDatasources.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MajorTableViewCell")! as! MajorTableViewCell
        cell.tableView.dataSource = minorDatasources[indexPath.row]
        return cell
    }
}

class MinorDatasource: NSObject, UITableViewDataSource {
    var labels:[String]

    init(labels:[String]) {
        self.labels = labels
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return labels.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MinorTableViewCell") as! MinorTableViewCell
        cell.textLabel?.text = labels[indexPath.row]
        return cell
    }
}

class MajorMinorViewController: UIViewController {

    var tableView: UITableView = {
        let v = UITableView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    var minorLabels: [[String]] = [
        ["One", "Two", "Three", "Four", "Five", "Six", "Seven"],
        ["A", "B", "C", "D", "E", "F", "G", "H"],
        ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
    ]

    var majorDatasource: MajorDatasource!

    var minorDatasources:[MinorDatasource] = [MinorDatasource]()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(tableView)

        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0.0),
            tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0.0),
            tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0.0),
            tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0.0),
            ])

        for labelArray in minorLabels {
            let mds = MinorDatasource(labels: labelArray)
            minorDatasources.append(mds)
        }

        tableView.register(MajorTableViewCell.self, forCellReuseIdentifier: "MajorTableViewCell")

        majorDatasource = MajorDatasource(minorDatasources: minorDatasources)

        tableView.dataSource = majorDatasource

    }

}

【讨论】:

    猜你喜欢
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多