Ios 展开和收缩标签在UITableViewCell中不起作用

Ios 展开和收缩标签在UITableViewCell中不起作用,ios,swift,Ios,Swift,我正在尝试使用UITableView,当用户单击标签时,单元格内容将展开或收缩 但是,我看到的行为是单元格将收缩,例如,我将标签的numberOfLines从0更改为1,然后标签将收缩。但是,当我将标签的numberOfLines从1更改为0时,它不会展开 我编写了一个简单的测试程序来说明我遇到的问题 我正在使用UITapGestureRecognitor处理标签的点击事件,这就是我展开或收缩标签的地方。有人知道我做错了什么吗 这是我的故事板和视图控制器代码 试一试 试一试 你几乎明白了,但有几

我正在尝试使用UITableView,当用户单击标签时,单元格内容将展开或收缩

但是,我看到的行为是单元格将收缩,例如,我将标签的numberOfLines从0更改为1,然后标签将收缩。但是,当我将标签的numberOfLines从1更改为0时,它不会展开

我编写了一个简单的测试程序来说明我遇到的问题

我正在使用UITapGestureRecognitor处理标签的点击事件,这就是我展开或收缩标签的地方。有人知道我做错了什么吗

这是我的故事板和视图控制器代码

试一试

试一试


你几乎明白了,但有几件事你应该关心

首先,使用UIgestureRecognitor处理标签—这相当开销。为此,UITableViewDelegate有自己的方法:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
其次,您使用的是自调整单元格大小,因为

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 75
有一条重要的规则:您应该将myLabel固定到superview的每一侧。请参见原因:

最后一步,当numberOfLines更改时,应设置单元格高度展开或折叠的动画,而无需重新加载单元格:

tableView.beginUpdates()
tableView.endUpdates()
:

您还可以使用此方法和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()
    }

}

你几乎明白了,但有几件事你应该关心

首先,使用UIgestureRecognitor处理标签—这相当开销。为此,UITableViewDelegate有自己的方法:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
其次,您使用的是自调整单元格大小,因为

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 75
有一条重要的规则:您应该将myLabel固定到superview的每一侧。请参见原因:

最后一步,当numberOfLines更改时,应设置单元格高度展开或折叠的动画,而无需重新加载单元格:

tableView.beginUpdates()
tableView.endUpdates()
:

您还可以使用此方法和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()
    }

}
做两件事

设置垂直内容拥抱优先级和 标签的垂直内容抗压优先级为1000。 更改标签的行数后,请调用tableView.BeginUpdate和tableView.EndUpdate 这肯定会奏效。

做两件事

设置垂直内容拥抱优先级和 标签的垂直内容抗压优先级为1000。 更改标签的行数后,请调用tableView.BeginUpdate和tableView.EndUpdate
这肯定会起作用。

你能尝试在handleCellTapped的末尾添加tableView.LayoutifNeed吗?@Karthick Ramesh-这没什么区别。你能尝试在handleCellTapped的末尾添加tableView.LayoutifNeed吗?@Karthick Ramesh-这没什么区别