这里是我的问题的视频: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)
}
我希望过渡到更加顺畅,我想要的东西,可以很容易地切换电池,同时保持在适当位置的主要标签,只显示字幕,然后标签。
您可以使用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
}
}
尝试这个:
tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
你好,你可以通过下面这个链接去克服的问题,
http://vasundharavision.com/blog/ios/expandable-tableview-without-third-party
我希望这个对你有用。