以编程方式创建扩展的UItableViewCell
我有一个tableviewcell,我想扩展和折叠。 我发现的所有示例都是Storyboard基础,我正在尝试以编程方式执行此操作。 我最初的想法是创建一个子视图并将其约束到内容视图,但是当我使用heightForRowAt
调整单元格的高度时,它也会增加内容视图的大小(这是有意义的)。 关于我应该怎么做的任何想法?
对于视觉参考,这是我想要发生的事情
使用垂直UIStackView
,底部视图isHidden
设置为true,然后点击(或任何扩展的触发器)只需更改isHidden = false
。 考虑到UIStackView
如何处理isHidden
,我想这将是最简单的。 另一种方法是设置自动布局约束,并通过将NSLayoutConstraint
的常量设置为0来更改底部视图的高度锚点。
无论如何,无论你选择哪个appraoch,你都必须告诉tableView刷新它的显示(来自viewcontroller):
func refreshTableAfterCellExpansion() { self.tableView.beginUpdates() self.tableView.setNeedsDisplay() self.tableView.endUpdates() }
例如,检查以下问题及其答案 。
使用playground的示例(带有UIStackView
,另一个使用相同的原理):
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()
我只想定义2个单元格类型,并选择适合tableView的那个(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)
您可以使用标志来指示是否展开特定的部分或行,并在UITableView上使用此方法:
reloadRows() reloadSections()
并根据标志更改heightForRow方法返回所需高度。 如果您希望一次扩展多行,则可以对数据源中的每个项使用ViewModel,并在调用didSelectItemAt或didDeselectItemAt方法时更新其中的标志,然后使用所需的动画重新加载行或节。