当用户选择或取消选择时,如何更改自定义UITableViewCell的高度



在我的项目中,我有一个UITableView,每当用户点击任何单元格时,该单元格的高度都会随着单元格内显示一些长文本而增加,当再次点击或点击另一个单元格时,单元格的高度会降低并显示一些短文本。(带有一些动画(

这是我的自定义手机代码:

class SomeCustomCell: UITableViewCell {

static let identifier = "SomeCustomCellId"
var shortDescLabel: AvatarLabel!
var longDescLabel: AvatarLabel!

override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
backgroundColor = selected ? UIColor.lightGray.withAlphaComponent(0.5) : .clear

if selected {
didSelected()
} else {
deSelected()
}
}

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

selectionStyle = .none

shortDescLabel = AvatarLabel()
shortDescLabel.translatesAutoresizingMaskIntoConstraints = false
addSubview(shortDescLabel)

NSLayoutConstraint.activate([
shortDescLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
shortDescLabel.topAnchor.constraint(equalTo: topAnchor, constant: 20),
shortDescLabel.heightAnchor.constraint(equalToConstant: 50),
shortDescLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10)
])

longDescLabel = AvatarLabel()
longDescLabel.alpha = 0.0
longDescLabel.numberOfLines = 0
longdateLabel.isHidden = true
longDescLabel.translatesAutoresizingMaskIntoConstraints = false
addSubview(longDescLabel)

NSLayoutConstraint.activate([
longDescLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
longDescLabel.topAnchor.constraint(equalTo: topAnchor, constant: 20),
longDescLabel.heightAnchor.constraint(equalToConstant: 100),
longDescLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10)
])
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func didSelected() {
longDescLabel.isHidden      = false
shortDescLabel.isHidden     = true
UIView.animate(withDuration: 0.5) { [weak self] in

self?.shortDescLabel.alpha  = 0.0
self?.longDescLabel.alpha   = 1.0
}
}

func deSelected() {

longDescLabel.isHidden      = true
shortDescLabel.isHidden     = false
backgroundColor = .clear

UIView.animate(withDuration: 0.5) { [weak self] in
self?.shortDescLabel.alpha  = 1.0
self?.longDescLabel.alpha   = 0.0
}
}

func setSomeCustomCell(_ someModel: SomeModel) {

shortDescLabel.text = someModel.shortText
longDescLabel.text  = someModel.longText
}
}

这是我的UITableView代码:

extension someViewController: UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

if someModels.count == 0 {
tableView.setEmptyView()
} else {
tableView.restore()
}

return someModels.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: SomeCustomCell.identifier) as? SomeCustomCell else {
return SomeCustomCell()
}
let item = someModels[indexPath.row]
cell. setSomeCustomCell(item)

return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

if selectedCellIndexPath == indexPath {
self.selectedCellIndexPath = nil
guard let cell = tableView.cellForRow(at: indexPath) as? SomeCustomCell else { return }
cell.deSelected()
} else {
self.selectedCellIndexPath = indexPath
}

tableView.beginUpdates()
tableView.endUpdates()
if selectedCellIndexPath != nil {
// This ensures, that the cell is fully visible once expanded
tableView.scrollToRow(at: indexPath, at: .none, animated: true)
}
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if selectedCellIndexPath == indexPath {
return 140
}
return 90
}
}

但有一个问题,当用户点击某个单元格并再次点击它(单元格先变大,然后变小(,向下滚动(所选单元格现在不再显示在屏幕上(,然后向上滚动查看该单元格时,该单元格的高度很小,但显示的是长数据(而不是短数据(。为什么会发生这种情况,以及如何解决这个问题?

调用自己的func来更改"选择/未选择";单元格的出现不会NOT通知表视图更改。

使用当前代码,当您第二次点击单元格时,您会告诉该单元格更改其外观,但据表视图所知,该单元格仍处于选中状态

因此,当你向下滚动然后向上滚动时,表视图是";重新选择";自动显示行。

将您的didSelectRowAt更改为:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedCellIndexPath == indexPath {
self.selectedCellIndexPath = nil
// tell the table view to deselect the row!
tableView.deselectRow(at: indexPath, animated: true)
//guard let cell = tableView.cellForRow(at: indexPath) as? SomeCustomCell else { return }
//cell.deSelected()
} else {
self.selectedCellIndexPath = indexPath
}

tableView.beginUpdates()
tableView.endUpdates()
if selectedCellIndexPath != nil {
// This ensures, that the cell is fully visible once expanded
tableView.scrollToRow(at: indexPath, at: .none, animated: true)
}
}

最新更新