You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UILabel调用sizeToFit后富文本内容被截断的解决方法求助

解决UILabel富文本末尾内容截断/不显示的问题

我来帮你分析下这个问题,大概率是手动布局和AutoLayout混用导致的约束冲突,再加上富文本加载的顺序不对,才会出现内容截断的情况。下面给你两个可行的解决方案:

方案一:使用纯AutoLayout(推荐,适配性更好)

你之前的代码里同时用了frame、sizeToFit和AutoLayout约束,这会让系统的布局引擎混乱——因为手动设置frame后,translatesAutoresizingMaskIntoConstraints默认是true,系统会自动生成一些约束,和你手动添加的centerY约束打架,最终导致label的高度被错误限制,内容显示不全。

修正后的代码如下:

let label = UILabel()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
// 关键:关闭自动转换约束,让我们完全控制布局
label.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(label)

// 用AutoLayout设置label的宽度(左右边距)和垂直居中
NSLayoutConstraint.activate([
    label.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16),
    label.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16),
    label.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
])

// 最后加载富文本
do {
    guard let htmlData = htmlString.data(using: .unicode, allowLossyConversion: true) else {
        print("无法将HTML字符串转换为Data")
        return
    }
    let attributedText = try NSAttributedString(
        data: htmlData,
        options: [.documentType: NSAttributedString.DocumentType.html],
        documentAttributes: nil
    )
    label.attributedText = attributedText
} catch {
    print("富文本加载失败:\(error)")
}

这样设置后,label会根据内容自动计算高度,同时保持左右边距和垂直居中,不会出现内容截断的问题。

方案二:坚持使用手动布局

如果你不想用AutoLayout,那就要避免添加任何约束,而是在加载完富文本后再计算label的尺寸并调整位置:

let label = UILabel()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
self.view.addSubview(label)

// 先加载富文本
do {
    guard let htmlData = htmlString.data(using: .unicode, allowLossyConversion: true) else {
        print("无法将HTML字符串转换为Data")
        return
    }
    let attributedText = try NSAttributedString(
        data: htmlData,
        options: [.documentType: NSAttributedString.DocumentType.html],
        documentAttributes: nil
    )
    label.attributedText = attributedText
} catch {
    print("富文本加载失败:\(error)")
}

// 根据内容计算合适的尺寸,再设置居中位置
let maxWidth = self.view.bounds.width - 32 // 左右各留16边距
let labelSize = label.sizeThatFits(CGSize(width: maxWidth, height: CGFloat.greatestFiniteMagnitude))
label.frame = CGRect(
    x: 16,
    y: (self.view.bounds.height - labelSize.height) / 2,
    width: maxWidth,
    height: labelSize.height
)

这里用sizeThatFits替代sizeToFit,可以更灵活地限制label的最大宽度,避免内容过宽导致的排版问题。

另外,你HTML里的 是不换行空格,一般不会导致截断,但如果后续还有类似特殊字符,可以先预处理HTML字符串再转换富文本。

内容的提问来源于stack exchange,提问作者Nazik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:27:47