以编程方式创建一个扩展的 UItableViewCell [英] Programmatically creating an expanding 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()
}
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屋!