问题描述
我有一个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.
无论如何,无论你选择哪个appraoch,你都必须告诉tableView刷新它的显示(来自viewcontroller):
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()
}
例如,请检查及其。
使用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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!