如何使用动态标签数量创建自定义UITableViewCell

时间:2019-05-30 05:32:04

标签: ios swift uitableview

tableview中的每个自定义单元格可以具有一个或两个或三个或更多标签,具体取决于从api返回的数据数量。

我尝试在cellForRowAtIndexPath方法的单元格中创建动态数量的标签。但是每次滚动时,所有这些标签都相互重叠。是否还有其他方法可以在单元格中创建动态数量的标签?

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

    let w : CGFloat = CGFloat(self.tableview.frame.size.width/3)
    var x : CGFloat = 0

    for index in 0...2
    {
        let label = UILabel(frame: CGRect(x: x, y: cell.frame.origin.y, width: w , height: cell.frame.size.height))
        let str = String(index)
        print(str)
        label.text = str
        cell.contentView.addSubview(label)
        print("x is" , x)
        x += w

    }

    return cell
}

4 个答案:

答案 0 :(得分:0)

  

您需要在单元格内部创建内部tableview,其效果要好于循环并手动创建标签。   您只需要在主单元格内创建tableview。对于内部tableview,创建带有标签thats的单元格,现在您可以根据需要返回单元格数。   希望对您有帮助。

答案 1 :(得分:0)

如果在您的单元格中没有在.xib文件中添加任何标签。 然后尝试

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

let w : CGFloat = CGFloat(self.tableview.frame.size.width/3)
var x : CGFloat = 0
for subView in cell.contentView.subviews{
     if subView.isKind(of: UILabel.self){
         return cell
     }
}

答案 2 :(得分:0)

这可以使用UIStackview实现。这是具有表视图的视图控制器的示例代码,其每行可以显示1、2或3个标签。 cellForRow数据源方法具有根据需要切换标签数量的逻辑。

import UIKit

class ViewController: UIViewController {

    // This array contains the sample data to populate the tableview. Each 
       element dictates the number of labels to be shown in the cell
    var tableData = [1,2,3,2,3,2]
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: 
IndexPath) -> UITableViewCell {

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

        let labelCount = tableData[indexPath.row]

        // Check the label count for the current row to decide how many labels to show.
        // Extra lables are hidden
        switch labelCount {
        case 1:
            cell.label1.isHidden = false
            cell.label2.isHidden = true
            cell.label3.isHidden = true
        case 2:
            cell.label1.isHidden = false
            cell.label2.isHidden = false
            cell.label3.isHidden = true
        default:
            cell.label1.isHidden = false
            cell.label2.isHidden = false
            cell.label3.isHidden = false
        }

        return cell
    }
}

LabelTableViewCell类是UITableViewCell的子类,并且包含UIStackView。堆栈视图处理垂直放置标签的任务。同样,当一个或多个标签(在Interface Builder中作为堆栈视图的排列的子视图添加)被隐藏时,堆栈视图的高度也会被调整。诀窍是在stackview的顶部到单元格内容视图的顶部之间以及相似的底部约束之间具有约束。这将确保当stackview的高度改变时,单元的高度也相应地改变。

我已将项目添加到GitHub,以更好地理解

这是结果的屏幕截图。

enter image description here

答案 3 :(得分:0)

使用约束来增加单元格的高度。在单元格中添加一个垂直的stackview。并在单元格类中创建一个函数,以根据参数值附加标签。

class PracLabelCell: UITableViewCell {
    let titleLabel = UILabel()
    let stackView = UIStackView()
    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() {
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        addSubview(titleLabel)

        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.alignment = .fill
        stackView.spacing = 2
        stackView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(stackView)

        titleLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
        titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20).isActive = true
        titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        titleLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true

        stackView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor).isActive = true
        stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20).isActive = true
        stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }
    func setup(names: [String]) {
        stackView.arrangedSubviews.forEach { stackView.removeArrangedSubview($0);$0.removeFromSuperview() }
        names.forEach {
            let label = UILabel()
            label.text = $0
            stackView.addArrangedSubview(label)
        }
    }
}

并通过tableView cellForRowAt方法传递值。

class TableViewController: UITableViewController {
    var namesArray = [["a","b","c"],["d","e"],["f"],["g","h"],[],["j"]]
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        tableView.register(PracLabelCell.self, forCellReuseIdentifier: "PracLabelCell")
    }
    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return namesArray.count
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "PracLabelCell", for: indexPath) as! PracLabelCell
        cell.titleLabel.text = "This cell has \(namesArray[indexPath.row].count) labels"
        cell.setup(names: namesArray[indexPath.row])
        return cell
    }
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
}

enter image description here