如何展开和折叠的tableview细胞编程动态高度?

问题描述 投票:1回答:3

这里是我的问题的视频:https://imgur.com/a/qvGSLfD

我的自定义单元格有2个标签:一个主标签和字幕标记,这两个被限制到该单元的内容查看layoutMarginsGuide四通八达。

首先,整个展开折叠机制似乎有点笨重,因为我来启用和停用的约束,然后重装indexPaths。

我试过这个方法:当我选择单元格,我停用负责设置只有一个标签,并激活约束双方,而当它崩溃我做相反的约束。我觉得这不是一个好办法,但我没能找到任何支持的动态单元格高度。

基本上,我已经做了这样的事情:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.row == selectedRowIndex {
        return 200 //Expanded
    }
    return tableView.rowHeight //Not expanded
}

但我不能只返回相同的号码,其尺寸不同的细胞。

这里是我的viewController类我的tableView代码:

 var tableView: UITableView = {
    let tv = UITableView(frame: .zero)
    tv.register(CustomCell.self, forCellReuseIdentifier: CustomCell.reuseIdentifier())
    tv.translatesAutoresizingMaskIntoConstraints = false
    tv.rowHeight = UITableView.automaticDimension
    tv.estimatedRowHeight = 60.0
    tv.estimatedSectionHeaderHeight = 0
    tv.estimatedSectionFooterHeight = 0
    tv.showsVerticalScrollIndicator = false
    tv.tableFooterView = UIView()
    tv.alwaysBounceVertical = true
    tv.decelerationRate = .fast
    tv.bounces = false
    tv.dataSource = self
    tv.delegate = self
    return tv
}()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.reuseIdentifier(), for: indexPath) as! CustomCell
    cell.bounds = CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 99999)
    cell.contentView.bounds = cell.bounds
    cell.layoutIfNeeded()
    cell.wordLabel.preferredMaxLayoutWidth = cell.wordLabel.frame.width
    cell.descriptionLabel.preferredMaxLayoutWidth = cell.descriptionLabel.frame.width

    //customize this later
    cell.backgroundColor = .white
    cell.set(content: datasource[indexPath.row])
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! CustomCell
    cell.toggle()
    tableView.reloadRows(at: [indexPath], with: .automatic)
}

以下是有关自定义单元格的功能:

var isExpanded: Bool!

private var singleLabelConstraints: [NSLayoutConstraint]!
private var doubleLabelConstraints: [NSLayoutConstraint]!

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

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

func toggle() {
    isExpanded = !isExpanded
    if isExpanded == false {
        print("collapsed")
        self.descriptionLabel.isHidden = true
        NSLayoutConstraint.activate(singleLabelConstraints)
        NSLayoutConstraint.deactivate(doubleLabelConstraints)
    } else if isExpanded == true {
        print("expanded")
        self.descriptionLabel.isHidden = false
        NSLayoutConstraint.deactivate(singleLabelConstraints)
        NSLayoutConstraint.activate(doubleLabelConstraints)
    }
}

func setupLabels() {
    isExpanded = false
    descriptionLabel.isHidden = true
    self.contentView.addSubview(wordLabel)
    self.contentView.addSubview(descriptionLabel)

    singleLabelConstraints = [
        wordLabel.leadingAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.leadingAnchor,
            constant: labelInsets.left
        ),
        wordLabel.topAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.topAnchor,
            constant: labelInsets.top
        ),
        wordLabel.trailingAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.trailingAnchor,
            constant: labelInsets.right
        ),
        wordLabel.bottomAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.bottomAnchor,
            constant: labelInsets.bottom
        )
    ]

    doubleLabelConstraints = [
        wordLabel.leadingAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.leadingAnchor,
            constant: labelInsets.left
        ),
        wordLabel.topAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.topAnchor,
            constant: labelInsets.top
        ),
        wordLabel.trailingAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.trailingAnchor,
            constant: labelInsets.right
        ),

        descriptionLabel.leadingAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.leadingAnchor,
            constant: labelInsets.left
        ),
        descriptionLabel.topAnchor.constraint(
            equalTo: self.wordLabel.bottomAnchor,
            constant: labelInsets.top
        ),
        descriptionLabel.trailingAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.trailingAnchor,
            constant: labelInsets.right
        ),
        descriptionLabel.bottomAnchor.constraint(
            equalTo: self.contentView.layoutMarginsGuide.bottomAnchor,
            constant: labelInsets.bottom
        )
    ]
    NSLayoutConstraint.activate(singleLabelConstraints)
}

我希望过渡到更加顺畅,我想要的东西,可以很容易地切换电池,同时保持在适当位置的主要标签,只显示字幕,然后标签。

ios swift uitableview tableview
3个回答
2
投票

您可以使用UIStackView的展开和折叠的tableview。你可以隐藏和显示的说明标签被选中的tableview单元格时。

class ViewController: UIViewController {
    var tableView: UITableView = {
        let tv = UITableView(frame: .zero)
        tv.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
        tv.translatesAutoresizingMaskIntoConstraints = false
        tv.rowHeight = UITableView.automaticDimension
        tv.estimatedRowHeight = 100.0
        tv.estimatedSectionHeaderHeight = 0
        tv.estimatedSectionFooterHeight = 0
        tv.showsVerticalScrollIndicator = false
        tv.tableFooterView = UIView()
        tv.alwaysBounceVertical = true
        tv.decelerationRate = .fast
        tv.bounces = false
        return tv
    }()
    var selectedCell:IndexPath?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(tableView)
        tableView.dataSource = self
        tableView.delegate = self
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[tableView]|", options: [], metrics: nil, views: ["tableView":tableView]))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: nil, views: ["tableView":tableView]))
    }


}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as? CustomCell ?? CustomCell()
        if let selectedCell = selectedCell, selectedCell == indexPath {
            cell.descriptionLabel.isHidden = false
        } else {
            cell.descriptionLabel.isHidden = true
        }
        return cell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        selectedCell = indexPath
        tableView.reloadData()
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }

}

class CustomCell: UITableViewCell {

    let stackView = UIStackView()
    let wordLabel = UILabel()
    let descriptionLabel = UILabel()

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

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

    func setupLabels() {

        selectionStyle = .none

        stackView.axis = .vertical
        stackView.distribution = .equalSpacing
        stackView.spacing = 5
        stackView.alignment = .fill
        stackView.translatesAutoresizingMaskIntoConstraints = false
        self.contentView.addSubview(stackView)

        wordLabel.translatesAutoresizingMaskIntoConstraints = false
        wordLabel.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lor"
        wordLabel.numberOfLines = 0
        wordLabel.lineBreakMode = .byWordWrapping
        stackView.addArrangedSubview(wordLabel)

        descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
        descriptionLabel.text = "It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
        descriptionLabel.numberOfLines = 0
        descriptionLabel.lineBreakMode = .byWordWrapping
        stackView.addArrangedSubview(descriptionLabel)

        wordLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 30).isActive = true
        descriptionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 30).isActive = true

        stackView.leadingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.leadingAnchor,constant: 10).isActive = true
        stackView.topAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.topAnchor,constant: 10).isActive = true
        stackView.trailingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.trailingAnchor,constant: 10).isActive = true
        stackView.bottomAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.bottomAnchor,constant: 10).isActive = true

    }
}

0
投票

尝试这个:

tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()

0
投票

你好,你可以通过下面这个链接去克服的问题,

http://vasundharavision.com/blog/ios/expandable-tableview-without-third-party

我希望这个对你有用。

© www.soinside.com 2019 - 2024. All rights reserved.