【问题标题】:UILabel not breaking lines in UITableViewCellUILabel 没有在 UITableViewCell 中换行
【发布时间】:2019-06-28 11:19:49
【问题描述】:

我正在构建一个带有类似信使的界面的应用程序。
我使用 tableView 来完成此操作。每个单元格包含一个 UIView - 消息气泡和一个 UILabel - 嵌套在 UIView 中的消息。
它适用于小尺寸的文本,但由于某种原因,当 UILabel 应该换行时,它不会,并且全部都在一行中。行数设置为零。

这是我的消息处理类:

    func commonInit() {

    print(MessageView.frame.height)
    MessageView.clipsToBounds = true
    MessageView.layer.cornerRadius = 15
    myCellLabel.numberOfLines = 0
    let bubbleSize = CGSize(width: self.myCellLabel.frame.width + 28, height: self.myCellLabel.frame.height + 20)
    print(bubbleSize.height)
    MessageView.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: bubbleSize.width, height: bubbleSize.height)


    if reuseIdentifier! == "Request" {
        MessageView.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner, .layerMinXMaxYCorner]
        MessageView.backgroundColor = UIColor(red: 0, green: 122/255, blue: 1.0, alpha: 1.0)
    } else  {
        MessageView.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner, .layerMaxXMaxYCorner]
        MessageView.backgroundColor = UIColor.lightGray
    }


}

单元格调用函数:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if queryCounter % 2 == 0 && indexPath.row % 2 == 0{
        cellReuseIdentifier = "Answer"

    } else {
        cellReuseIdentifier = "Request"
    }

    let cell:MessageCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MessageCell
    cell.myCellLabel.textColor = UIColor.white
    cell.myCellLabel.text = self.messages[indexPath.row]
    let height = cell.myCellLabel.text!.height(withConstrainedWidth: cell.myCellLabel.frame.width, font: cell.myCellLabel.font)
    print(height)
    cell.contentView.transform = CGAffineTransform(scaleX: 1, y: -1)

    return cell
}

高度变量是根据文本大小计算的。它表明文本大小是正常计算的 - 考虑换行符。 我无法根据此计算修改单元格高度 - 我没有尝试过任何工作。 我认为这可能是一个约束问题。
我的约束:

我如何使线条中断?请帮忙。

编辑:我只是注意到MessageView.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: bubbleSize.width, height: bubbleSize.height) 对消息气泡没有任何影响。

【问题讨论】:

  • lineBreakMode 怎么样? myCellLabel.lineBreakMode = .byCharWrapping
  • 我在故事板中添加了它。
  • 将其添加到代码中也不起作用:/
  • 确保您没有在情节提要中为您的 UILable 设置高度限制。
  • @HastiRanjkesh 高度未设置。

标签: ios swift uitableview uilabel


【解决方案1】:

经过几个小时的尝试,我设法修复了它。问题在于约束。
1. 正如您在这个旧布局中看到的那样。 UIView 除了左边之外的所有地方都受到限制-> 那是文本所在的位置。

  1. 在初始化任何文本之前调用 UITableViewCell 的 commonInit() 方法。这不好,因为所有单元格大小调整都基于尚未传递给单元格的文本 -> 在单元格初始化后移动方法。

        let cell:MessageCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MessageCell
    cell.myCellLabel.text = self.messages[indexPath.row]
    
    //Before calling commonInit() we need to adjust the cell height. 
    let height = cell.myCellLabel.text!.heightForView(text: cell.myCellLabel.text!, font: cell.myCellLabel.font, width: self.view.frame.width / 2)
    
    // Then we set the width of the UILabel for it to break lines at 26 characters
    if cell.myCellLabel.text!.count > 25 {
        tableView.rowHeight = height + 20
        cell.myCellLabel.widthAnchor.constraint(equalToConstant: cell.frame.width / 2).isActive = true
        cell.updateConstraints()
    
    }
    // Calling commonInit() after adjustments 
    cell.commonInit()
    
    cell.contentView.transform = CGAffineTransform(scaleX: 1, y: -1)
    
    return cell
    
  2. 然后我们需要更新约束,以便 UIView 和 UILabel 随单元格高度调整大小。

  1. 完成。现在它可以根据需要工作。感谢您的所有建议!

【讨论】:

    【解决方案2】:

    尝试根据标签宽度和文本字体找到标签高度,然后将标签高度约束设置为该值。

    extension String {
        func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
            let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
            let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)
    
            return ceil(boundingBox.height)
        }
    }
    

    类似这样的:

    let textHeight = yourtext.height(withConstrainedWidth: yourlabel.frame.width, font: font)
    yourLabel.heightAnchor.constraint(equalToConstant: textHeight).isActive = true
    

    【讨论】:

      【解决方案3】:

      在使用自动布局时设置框架不起作用。

      如果没有整个上下文,我无法说出这里到底发生了什么,但重用单元格和自动布局时的一些常见缺陷是:

      1. 忘记为单元格设置自动高度(手动展开情节提要中的单元格将覆盖此设置)
      2. Tableview 有时也需要estimatedHeight 才能正常工作
      3. 添加内容后有时需要拨打setNeedsLayout 细胞

      检查控制台,如果有一些关于打破约束的警告,你可以很容易地发现那里的问题。

      【讨论】:

      • 感谢您的回答。做 1、2 和 3 但不幸的是同样的问题。没有警告。
      • 您是否尝试过在调试视图层次结构中使用视图检查器?您有时可以通过查看分解后的视图来推断发生了什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多