以编程方式创建一个扩展的 UItableViewCell [英] Programmatically creating an expanding UItableViewCell

查看:29
本文介绍了以编程方式创建一个扩展的 UItableViewCell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 tableviewcell,我想在点击时展开和折叠.我发现的所有示例都是基于 Storyboard 的,我正在尝试以编程方式执行此操作.我最初的想法是创建一个子视图并将其约束到内容视图,但是当我使用 heightForRowAt 调整单元格的高度时,它也会增加内容视图的大小(这是有道理的).关于我应该如何解决这个问题的任何想法?

I have a tableviewcell that I want to expand and collapse on tap. All the examples I have found are Storyboard base and I am trying to do this programmatically. What I thought initially was to create a subview and constrain it to the content view but when I adjust the height of the cell with heightForRowAt it also increases the size of the content view (which makes sense). Any thoughts on how I should go about this?

这里是我想要的视觉参考

For visual reference here is what I want to happen

推荐答案

使用垂直 UIStackView 并将底部视图 isHidden 设置为 true,然后点击(或任何展开的触发器)只需更改 isHidden = false.我想这是最简单的,考虑到 UIStackView 如何处理 isHidden.另一种方法是设置自动布局约束,并通过将 NSLayoutConstraint 的常量设置为 0 来更改底部视图的高度锚点.

Use vertical UIStackView with the bottom view isHidden set to true, then on tap (or whatever is the trigger of the expand) just change the isHidden = false. I guess that would be the easiest, considering how UIStackView deals with isHidden. Another approach is to setup autolayout constraints, and change height anchor of the bottom view by setting NSLayoutConstraint's constant to 0.

无论如何,无论您选择哪种方法,您都必须告诉 tableView 刷新其显示(来自视图控制器):

Anyway, whichever of the appraoch will you choose, you will have to tell the tableView to refresh its display (from the viewcontroller):

func refreshTableAfterCellExpansion() {
    self.tableView.beginUpdates()
    self.tableView.setNeedsDisplay()
    self.tableView.endUpdates()
}

例如,检查以下 SO 问题 及其答案.

E.g., check following SO question and its answer.

一个使用 Playgrounds 的例子(一个使用 UIStackView,另一个使用相同的原理):

An example using playgrounds (the one with the UIStackView, the other one uses the same principle):

import UIKit
import PlaygroundSupport

class ExpandableCellViewController: UITableViewController, ExpandableCellDelegate {

    override func loadView() {
        super.loadView()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 44
        tableView.register(ExpandableCell.self, forCellReuseIdentifier: "expandableCell")
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "expandableCell", for: indexPath) as! ExpandableCell
        cell.delegate = self
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? ExpandableCell {
            cell.isExpanded = true
        }
    }

    override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? ExpandableCell {
            cell.isExpanded = false
        }
    }

    func expandableCellLayoutChanged(_ expandableCell: ExpandableCell) {
        refreshTableAfterCellExpansion()
    }

    func refreshTableAfterCellExpansion() {
        self.tableView.beginUpdates()
        self.tableView.setNeedsDisplay()
        self.tableView.endUpdates()
    }
}

protocol ExpandableCellDelegate: class {
    func expandableCellLayoutChanged(_ expandableCell: ExpandableCell)
}

class ExpandableCell: UITableViewCell {
    weak var delegate: ExpandableCellDelegate?

    fileprivate let stack = UIStackView()
    fileprivate let topView = UIView()
    fileprivate let bottomView = UIView()

    var isExpanded: Bool = false {
        didSet {
            bottomView.isHidden = !isExpanded
            delegate?.expandableCellLayoutChanged(self)
        }
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        selectionStyle = .none

        contentView.addSubview(stack)
        stack.addArrangedSubview(topView)
        stack.addArrangedSubview(bottomView)

        stack.translatesAutoresizingMaskIntoConstraints = false
        topView.translatesAutoresizingMaskIntoConstraints = false
        bottomView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            stack.topAnchor.constraint(equalTo: contentView.topAnchor),
            stack.leftAnchor.constraint(equalTo: contentView.leftAnchor),
            stack.rightAnchor.constraint(equalTo: contentView.rightAnchor),
            stack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),

            topView.heightAnchor.constraint(equalToConstant: 50),

            bottomView.heightAnchor.constraint(equalToConstant: 30),
            ])

        stack.axis = .vertical
        stack.distribution = .fill
        stack.alignment = .fill
        stack.spacing = 0

        topView.backgroundColor = .red
        bottomView.backgroundColor = .blue
        bottomView.isHidden = true
    }

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

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = ExpandableCellViewController()

这篇关于以编程方式创建一个扩展的 UItableViewCell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆