Вот видео моей проблемы: https://imgur.com/a/qvGSLfD
Моя пользовательская ячейка имеет 2 метки: одну основную метку и метку субтитра, обе из которых ограничены contentView layoutMarginsGuide ячейки во всех направлениях.
Прежде всего, весь механизм разворачивания развертывания кажется немного неуклюжим, поскольку я активирую и деактивирую ограничения, а затем перезагружаю indexPaths.
Я попробовал этот подход: когда я выбираюВ ячейке я деактивирую ограничения, которые отвечают за установку только одной метки, и активирую ограничения для обеих, а когда она сворачивается, я делаю наоборот.Мне кажется, что это не очень хороший подход, но я не смог найти ничего, что поддерживало бы динамическую высоту ячеек.
В принципе, я мог бы сделать что-то вроде этого:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == selectedRowIndex {
return 200 //Expanded
}
return tableView.rowHeight //Not expanded
}
, ноЯ не могу просто вернуть одно и то же число для ячеек с разным размером.
Вот мой код tableView в моем классе viewController:
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)
}
Вот соответствующие пользовательские функции Cell:
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)
}
Я ожидал, что переход будет более плавным, и я хочу что-то, что может легко переключать ячейку при сохранении основной метки на месте и просто отображать метку субтитров.