我正在构建一个带有Messenger界面的应用程序。
我使用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
}
height变量是根据文本大小计算的。它表明文本大小是正常计算的-考虑到换行符。
我无法根据此计算来修改像元高度-我尝试过的任何方法都无效。
我认为这可能是一个约束问题。
我的约束:
如何使行断开?请帮忙。
编辑:我只是注意到MessageView.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: bubbleSize.width, height: bubbleSize.height)
对消息气泡没有任何影响。
答案 0 :(得分:1)
使用自动布局时设置框架不起作用。
在没有整个上下文的情况下我无法确切地说出会发生什么,但是在重复使用单元格和自动布局时,常见的陷阱有:
setNeedsLayout
细胞检查控制台,如果有关于违反约束的警告,则可以轻松地在其中找到问题。
答案 1 :(得分:1)
尝试根据标签宽度和文本字体查找标签高度,然后将标签高度约束设置为此。
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
答案 2 :(得分:1)
尝试了多个小时后,我设法对其进行了修复。问题出在约束上。
1.如您所见,在此旧版式中。 UIView被限制在各处,除了文本的左边->。
在初始化任何文本之前,将调用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