首页 > 解决方案 > 根据父 UITableVIew 的节索引设置嵌套 UITableView 的行数

问题描述

我有一个UITableView里面UITableViewCell。我根据以下数组设置父/子表视图的行数:

articlesArray = [articleTemplateStruct(articleName: "", clauses: [""], payments: [paymentStruct(amount: "", desc: "")]), articleTemplateStruct(articleName: "", clauses: ["", ""], payments: [paymentStruct(amount: "", desc: ""), paymentStruct(amount: "", desc: "")]) ]

对于我设置的第一个 tableView 部分:

func numberOfSections(in tableView: UITableView) -> Int {
    if(tableView == articleTableView){
        return articlesArray.count
    }else{
       return 1
    }
}

对于第二个 tableView 我设置 numberOfRowsInSection:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if(tableView == articleTableView){
        return 1
    }else if(tableView.tag == 10){
        return articlesArray[section].clauses.count
    }else{
        return 1
    }
}

问题就在这里,在 numberOfRowsInSection 函数中,当我想使用标签为 10 的表的部分时,我需要访问其中 tableview 所在的 articleTableView 部分的部分!我不知道任何人都可以理解我想要什么或不想要什么!

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(tableView == articleTableView){
    let cell = tableView.dequeueReusableCell(withIdentifier: "ContractTemplate", for: indexPath) as! ContractTemplateTableViewCell

    self.functions.enterValue(textfield: cell.articleTitle, phText: langc.article)

    cell.separatorInset = .zero


    cell.clauseTableView.register(UINib(nibName: "ContractTemplateSubjectsTableViewCell", bundle: nil), forCellReuseIdentifier: "ContractTemplateSubjects")
    cell.paymentTableView.register(UINib(nibName: "ContractTemplatePaymentTableViewCell", bundle: nil), forCellReuseIdentifier: "ContractTemplatePayment")


    cell.clauseTableView.delegate = self
    cell.clauseTableView.dataSource = self
    cell.clauseTableView.reloadData()
    cell.clauseTableView.tableFooterView = UIView()


    cell.clauseTableView.sizeToFit()

    cell.clauseTableConst.constant = cell.clauseTableView.contentSize.height

    let artTableHeight = self.articleTableView.contentSize.height

    tableViewClause = cell.clauseTableView
    clauseTableFlag = true

    cell.paymentTableView.delegate = self
    cell.paymentTableView.dataSource = self
    cell.paymentTableView.reloadData()
    cell.paymentTableView.tableFooterView = UIView()


    cell.paymentTableConst.constant = cell.paymentTableView.contentSize.height


    articleTableConst.constant = artTableHeight + cell.clauseTableView.contentSize.height + cell.paymentTableView.contentSize.height


    containerHeightConst.constant = articleTableView.contentSize.height + 281

    cell.selectionStyle = .none

    cell.add.tag = indexPath.section

    cell.add.addTarget(self, action: #selector(addArticle), for: .touchUpInside)

    return cell

}else if(tableView.tag == 10){


    let cell = tableView.dequeueReusableCell(withIdentifier: "ContractTemplateSubjects", for: indexPath) as! ContractTemplateSubjectsTableViewCell

    self.functions.textArea(textArea: cell.subjectDesc, text: self.langc.descriptionTxt)

    cell.tag = indexPath.section*1000 + indexPath.row
    cell.add.addTarget(self, action: #selector(addClause), for: .touchUpInside)

    cell.separatorInset = .zero

    return cell
}
else{
    let cell = tableView.dequeueReusableCell(withIdentifier: "ContractTemplatePayment", for: indexPath) as! ContractTemplatePaymentTableViewCell

    cell.paymentTitle.textColor = titleColor

    cell.paymentTitle.text = self.langc.payment + " " + String(indexPath.row+1)

    self.functions.enterValue(textfield: cell.amount, phText: self.langc.amount)

    self.functions.enterValue(textfield: cell.shortText, phText: self.langc.shortText)

    cell.add.tag = indexPath.section*1000 + indexPath.row

    cell.add.addTarget(self, action: #selector(addPayment), for: .touchUpInside)

    cell.separatorInset = .zero

    return cell
}

标签: swiftuitableviewmultidimensional-array

解决方案


我想引入一个更好的结构来允许每个类是单一的责任,例如 articleTableView 的委托方法将在其父类中,而 ClausesTableView 的委托方法将在单元格内,如下所示:

ViewController.swift

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    private let tableView = UITableView()

    var articlesArray = [
        ArticleTemplate(articleName: "", clauses: ["A1"], payments: [Payment(amount: "", desc: "")]),
        ArticleTemplate(articleName: "", clauses: ["B1", "B2"], payments: [Payment(amount: "", desc: ""), Payment(amount: "", desc: "")])
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .white

        self.tableView.backgroundColor = .clear
        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.register(ArticleTableViewCell.self, forCellReuseIdentifier: "ArtCellId")
        self.tableView.translatesAutoresizingMaskIntoConstraints = false
        self.tableView.tableFooterView = UIView()

        self.view.addSubview(tableView)
        tableView.topAnchor.constraint(equalTo: self.view.layoutMarginsGuide.topAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: self.view.layoutMarginsGuide.bottomAnchor).isActive = true
        tableView.leadingAnchor.constraint(equalTo: self.view.layoutMarginsGuide.leadingAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: self.view.layoutMarginsGuide.trailingAnchor).isActive = true
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return self.articlesArray.count
    }

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

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ArtCellId", for: indexPath) as! ArticleTableViewCell
        cell.setData(article: self.articlesArray[indexPath.section])
        return cell
    }
}

ArticleTableViewCell.swift

class ArticleTableViewCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate {

    let clausesTableView = UITableView()
    let clausesTableViewHeight: NSLayoutConstraint
    var clauses: [String]!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        self.clausesTableViewHeight = clausesTableView.heightAnchor.constraint(equalToConstant: 0)
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.setupUI()
        self.clausesTableViewHeight.isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func prepareForReuse() {
        super.prepareForReuse()

        self.clauses = nil
        self.clausesTableView.dataSource = nil
        self.clausesTableView.delegate = nil
    }

    private func setupUI() {
        self.selectionStyle = .none

        self.clausesTableView.isScrollEnabled = false
        self.clausesTableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellId")
        self.clausesTableView.translatesAutoresizingMaskIntoConstraints = false
        self.contentView.addSubview(clausesTableView)
        self.clausesTableView.topAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.topAnchor).isActive = true
        self.clausesTableView.bottomAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.bottomAnchor).isActive = true
        self.clausesTableView.leadingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.leadingAnchor).isActive = true
        self.clausesTableView.trailingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.trailingAnchor).isActive = true
    }

    func setData(article: ArticleTemplate) {
        self.clauses = article.clauses
        self.clausesTableViewHeight.constant = CGFloat(44 * self.clauses.count)
        self.clausesTableView.delegate = self
        self.clausesTableView.dataSource = self
    }

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

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

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

还更改了一些成员/结构的名称以遵循命名约定:

struct Payment {
    let amount: String
    let desc: String
}
struct ArticleTemplate {
    let articleName: String
    let clauses: [String]
    let payments: [Payment]
}

推荐阅读