Как создать Custom UITableViewCell с динамическим количеством меток - PullRequest
0 голосов
/ 30 мая 2019

каждая пользовательская ячейка в табличном представлении может иметь одну, две, три или более меток в зависимости от количества данных, возвращаемых из 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 голосов
/ 30 мая 2019

Используйте ограничения для увеличения высоты ячеек.Добавьте вертикальный вид стека в ячейку.И создайте функцию в классе ячеек для добавления меток на основе значений аргументов.

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

0 голосов
/ 30 мая 2019

, если в вашей ячейке вы не добавили ярлык в файл .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
     }
}
0 голосов
/ 30 мая 2019

Это может быть достигнуто с помощью 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. Представление стека решает задачу размещения меток по вертикали. Кроме того, поскольку одна или несколько меток (которые добавляются как упорядоченные подпредставления представления стека в Интерфейсном Разработчике) скрыты, высота представления стека корректируется. Хитрость заключается в том, чтобы иметь ограничения между вершиной стека и верхней частью представления содержимого ячейки и аналогичными нижними ограничениями. Это гарантирует, что при изменении высоты стека высота ячейки также изменяется соответственно.

Я добавил проект в GitHub для лучшего понимания

Вот скриншот с результатом.

enter image description here

0 голосов
/ 30 мая 2019

вам нужно создать внутреннее представление таблицы внутри ячейки, это лучше, чем цикл, и создать метку вручную. вам просто нужно создать табличное представление внутри вашей основной ячейки. для внутреннего табличного представления создайте ячейку с меткой, и теперь вы можете возвращать количество ячеек, сколько хотите. надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...