我正在尝试使用UITableView并具有将在用户单击标签时扩展或收缩的单元格内容。
但是,我看到的行为是单元格将收缩(例如,我将标签的numberOfLines从0更改为1,然后标签将收缩)。但是,当我将标签的numberOfLines从1更改为0时,它不会扩展。
我整理了一个简单的测试程序来显示我遇到的问题。
我正在使用UITapGestureRecognizer来处理标签的轻击事件,这就是我扩展或收缩标签的地方。有人知道我在做什么错吗?
这是我的情节提要和视图控制器代码。
import UIKit
class MyCell : UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
}
class TableViewController: UITableViewController {
let cellID = "cell"
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 75
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 12
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "section " + String(section)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 4
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: self.cellID, for: indexPath) as! MyCell
cell.myLabel.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleCellTapped(_:)))
cell.myLabel!.addGestureRecognizer(tapGesture)
// Configure the cell...
if indexPath.row % 2 == 0 {
cell.myLabel?.numberOfLines = 1
cell.myLabel.text = "This is some long text that should be truncated. It should not span over multiple lines. Let's hope this actually works. \(indexPath.row)"
} else {
cell.myLabel?.numberOfLines = 0
cell.myLabel.text = "This is some really, really long text. It should span over multiple lines. Let's hope this actually works. \(indexPath.row)"
}
return cell
}
@objc func handleCellTapped(_ sender: UITapGestureRecognizer) {
print("Inside handleCellTapped...")
guard let label = (sender.view as? UILabel) else { return }
//label.translatesAutoresizingMaskIntoConstraints = false
// expand or contract the cell accordingly
if label.numberOfLines == 0 {
label.numberOfLines = 1
} else {
label.numberOfLines = 0
}
}
}
答案 0 :(得分:2)
做两件事。
这肯定可以工作。
答案 1 :(得分:1)
尝试
tableView.beginUpdates()
if label.numberOfLines == 0 {
label.numberOfLines = 1
} else {
label.numberOfLines = 0
}
tableView.endUpdates()
答案 2 :(得分:1)
您几乎明白了,但这是您应该注意的几件事。
首先,通过label
处理UIGestureRecognizer
,这是相当大的开销。为此,UITableViewDelegate
有自己的方法:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
其次,由于以下原因,您正在使用自动调整大小的单元格
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 75
有一个重要的规则:您应将myLabel
固定在超级视图的每一侧(请参阅official docs为何):
最后一步,当numberOfLines
更改时,您应该为cell
设置高度(展开或折叠)动画,而无需重新加载单元格:
tableView.beginUpdates()
tableView.endUpdates()
Docs:
您还可以在不重新加载单元格的情况下,使用此方法以及endUpdates()方法为行高设置动画效果。
完整代码:
class MyCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
}
class TableViewController: UITableViewController {
let cellID = "cell"
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 75
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 12
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "section " + String(section)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: self.cellID, for: indexPath) as! MyCell
cell.selectionStyle = .none // remove if you need cell selection
if indexPath.row % 2 == 0 {
cell.myLabel?.numberOfLines = 1
cell.myLabel.text = "This is some long text that should be truncated. It should not span over multiple lines. Let's hope this actually works. \(indexPath.row)"
} else {
cell.myLabel?.numberOfLines = 0
cell.myLabel.text = "This is some really, really long text. It should span over multiple lines. Let's hope this actually works. \(indexPath.row)"
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
guard let cell = tableView.cellForRow(at: indexPath) as? MyCell else { return }
cell.myLabel.numberOfLines = cell.myLabel.numberOfLines == 0 ? 1 : 0
tableView.beginUpdates()
tableView.endUpdates()
}
}