代码之家  ›  专栏  ›  技术社区  ›  dcp

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

  •  1
  • dcp  · 技术社区  · 6 年前

    我试图使用UITableView和单元格内容将扩大或收缩时,用户点击标签。

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

    我使用UITapGestureRecognizer来处理标签的tap事件,这就是我展开或收缩标签的地方。有人知道我做错了什么吗?

    enter image description here

    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
            }
        }
    }
    
    3 回复  |  直到 6 年前
        1
  •  1
  •   pacification    6 年前

    你差点就明白了,但有几件事你应该关心。

    首先,处理好 label 通过 UIGestureRecognizer 相当高的开销。为此目的 UITableViewDelegate 有自己的方法:

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

    第二,你使用的是自动调整大小的单元格,因为

    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 75
    

    有一条重要的规则:你应该用别针 myLabel 到superview的每一侧(请参见 official docs 原因):

    enter image description here

    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()
        }
    
    }
    
        2
  •  2
  •   Shubham    6 年前

    做两件事。

    1. 垂直内容优先 垂直内容压缩阻力优先级 标签的最大值为1000。
    2. 更改标签的行数后,调用

    这肯定管用。

        3
  •  1
  •   J.CHE    6 年前

    tableView.beginUpdates()
    if label.numberOfLines == 0 {
        label.numberOfLines = 1
    } else {
        label.numberOfLines = 0
    }
    tableView.endUpdates()