多行 UILabel 导致额外填充
Multi-line UILabel causing extra padding
我有一个 collectionView 单元格,它有一个标签和一个 imageView。 imageView 距离 cell 顶部 8 points,label 顶部距离 imageView 底部 8 points,label 底部距离 cell 底部 8 points。标签在距离单元格右边缘 -10 点时换行。
标签中的文本可以跨越多行。我在 collectionView 的 sizeForItem
中使用以下函数来计算标签的高度:
func estimatedLabelHeight(text: String, width: CGFloat, font: UIFont) -> CGFloat {
let size = CGSize(width: width, height: 1000)
let options = NSStringDrawingOptions.usesFontLeading.union([.usesLineFragmentOrigin, .usesFontLeading])
let attributes = [NSAttributedStringKey.font: font]
let rectangleHeight = String(text).boundingRect(with: size, options: options, attributes: attributes, context: nil).height
return rectangleHeight
}
单元格正确扩展,但标签添加了额外的填充,我不知道如何去掉它。
这是一个正确换行的 22 号多行标签。我在 3D 检查器中拍了张照片。如您所见,标签文本上方和下方的顶部和底部有相当多的填充。标签在 imageView 下方的 8 点间距是正确的,但额外的填充使其看起来像 24 点间距。
奇怪的是,即使我将标签的大小减小到 16,额外的填充仍然存在。
如何删除此填充?
调用estimatedLabelHeight函数的collectionView的sizeForItem:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let profileImageViewHeight: CGFloat = 50 // imageView height is set to 50 inside the cell
let padding: CGFloat = 24 // 8 x 8 x 8 the vertical padding inside the cell between the titleLabel, the imageView, and the cell
// estimatedLabelHeight is called here
let titleLabelHeight = estimatedLabelHeight(text: "some very very long text...", width: view.frame.width - 20, font: UIFont.systemFont(ofSize: 22))
let totalHeightOfCell = titleLabelHeight + profileImageViewHeight + padding
return CGSize(width: view.frame.width, height: totalHeightOfCell)
}
单元格:
class MyCell: UICollectionViewCell{
let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 22)
label.textColor = UIColor.black
label.textAlignment = .left
label.sizeToFit()
label.numberOfLines = 0
return label
}()
let profileImageView: UIImageView = {
// created it...
}
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(profileImageView)
addSubview(titleLabel)
profileImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true
profileImageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 50).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 50).isActive = true
titleLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 8).isActive = true
titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
titleLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
titleLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8).isActive = true
// I tried to set the label's height using the below but the same padding issue occured
// let titleLabelHeight = estimatedLabelHeight(text: titleLabel.text!, width: self.frame.width - 20, font: UIFont.systemFont(ofSize: 22))
// titleLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: titleLabelHeight).isActive = true
}
}
问题是我自己粗心造成的。 @CSmith 在 sizeForItem 和单元格框架中测量高度的技巧帮助我缩小了范围。
在 collectionView 单元格内的项目中,我将 imageView 的底部锚点设置为 8 而不是 -8,在 collectionView 的 sizeForItem 中,我的总高度为 24。有一个冲突,因为我在里面有一个 8该单元格应该在 collectionView 中为 16,并且这种不匹配以某种方式拉伸了标签。一旦我更正它并更改 imageView 的底部锚点 -8 一切都匹配并且标签的填充问题得到解决。
我有一个 collectionView 单元格,它有一个标签和一个 imageView。 imageView 距离 cell 顶部 8 points,label 顶部距离 imageView 底部 8 points,label 底部距离 cell 底部 8 points。标签在距离单元格右边缘 -10 点时换行。
标签中的文本可以跨越多行。我在 collectionView 的 sizeForItem
中使用以下函数来计算标签的高度:
func estimatedLabelHeight(text: String, width: CGFloat, font: UIFont) -> CGFloat {
let size = CGSize(width: width, height: 1000)
let options = NSStringDrawingOptions.usesFontLeading.union([.usesLineFragmentOrigin, .usesFontLeading])
let attributes = [NSAttributedStringKey.font: font]
let rectangleHeight = String(text).boundingRect(with: size, options: options, attributes: attributes, context: nil).height
return rectangleHeight
}
单元格正确扩展,但标签添加了额外的填充,我不知道如何去掉它。
这是一个正确换行的 22 号多行标签。我在 3D 检查器中拍了张照片。如您所见,标签文本上方和下方的顶部和底部有相当多的填充。标签在 imageView 下方的 8 点间距是正确的,但额外的填充使其看起来像 24 点间距。
奇怪的是,即使我将标签的大小减小到 16,额外的填充仍然存在。
如何删除此填充?
调用estimatedLabelHeight函数的collectionView的sizeForItem:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let profileImageViewHeight: CGFloat = 50 // imageView height is set to 50 inside the cell
let padding: CGFloat = 24 // 8 x 8 x 8 the vertical padding inside the cell between the titleLabel, the imageView, and the cell
// estimatedLabelHeight is called here
let titleLabelHeight = estimatedLabelHeight(text: "some very very long text...", width: view.frame.width - 20, font: UIFont.systemFont(ofSize: 22))
let totalHeightOfCell = titleLabelHeight + profileImageViewHeight + padding
return CGSize(width: view.frame.width, height: totalHeightOfCell)
}
单元格:
class MyCell: UICollectionViewCell{
let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 22)
label.textColor = UIColor.black
label.textAlignment = .left
label.sizeToFit()
label.numberOfLines = 0
return label
}()
let profileImageView: UIImageView = {
// created it...
}
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(profileImageView)
addSubview(titleLabel)
profileImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true
profileImageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 50).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 50).isActive = true
titleLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 8).isActive = true
titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
titleLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
titleLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8).isActive = true
// I tried to set the label's height using the below but the same padding issue occured
// let titleLabelHeight = estimatedLabelHeight(text: titleLabel.text!, width: self.frame.width - 20, font: UIFont.systemFont(ofSize: 22))
// titleLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: titleLabelHeight).isActive = true
}
}
问题是我自己粗心造成的。 @CSmith 在 sizeForItem 和单元格框架中测量高度的技巧帮助我缩小了范围。
在 collectionView 单元格内的项目中,我将 imageView 的底部锚点设置为 8 而不是 -8,在 collectionView 的 sizeForItem 中,我的总高度为 24。有一个冲突,因为我在里面有一个 8该单元格应该在 collectionView 中为 16,并且这种不匹配以某种方式拉伸了标签。一旦我更正它并更改 imageView 的底部锚点 -8 一切都匹配并且标签的填充问题得到解决。