YYLabel 下Masnory 约束的问题

在使用YYLabel进行布局约束的时候,会出现创建新的View上,高度正确,但是YYLabel的高度不对的问题。

之前调试了很久都没有很好的解决,现在用Cursor分析解决了。这里记录下。

原理

这行代码之所以能修复 bug,要理解 YYLabel 的 intrinsicContentSize 工作机制以及 Auto Layout 的 layout 生命周期顺序。


Auto Layout layout 生命周期顺序

setNeedsUpdateConstraints()
       ↓
updateConstraints()       ← 我们在这里
       ↓
Auto Layout 求解约束 → 调用每个 view 的 intrinsicContentSize
       ↓
layoutSubviews()          ← 之前只在这里设置 preferredMaxLayoutWidth(太晚了)

YYLabel.intrinsicContentSize 的行为

YYLabel 的 intrinsicContentSize 内部逻辑大致是:

override var intrinsicContentSize: CGSize {
    if preferredMaxLayoutWidth > 0 {
        // ✅ 同步调用 sizeThatFits — 立即计算多行高度,不依赖 textLayout
        return sizeThatFits(CGSize(width: preferredMaxLayoutWidth, height: .greatestFiniteMagnitude))
    } else {
        // ❌ 依赖异步生成的 textLayout,第一次为 nil → 返回错误高度
        return textLayout?.textBoundingSize ?? super.intrinsicContentSize
    }
}

Bug 的根因

preferredMaxLayoutWidth 原来只在 layoutSubviews 里设置:

updateConstraints 运行
  → Auto Layout 询问 titleLabel.intrinsicContentSize
      → preferredMaxLayoutWidth == 0(还没到 layoutSubviews)
      → 走 else 分支 → textLayout 是 nil(YYLabel 异步渲染还没完成)
      → 返回错误高度(0 或 27 的最小值)
  → topView 高度 = 13 + 27 + 3 + 0 + 13 = 56 < 72 → 钳位到 72
layoutSubviews 才设置 preferredMaxLayoutWidth  ← 已经太晚了

Fix 的原理

preferredMaxLayoutWidth 提前到 updateConstraints 里设置,让它先于 Auto Layout 询问 intrinsicContentSize 就位:

updateConstraints 运行
  → preferredMaxLayoutWidth = contentView.bounds.width - 40 - 112 = 278  ← 提前设置
  → super.updateConstraints() 触发 Auto Layout 重新求解
  → Auto Layout 询问 titleLabel.intrinsicContentSize
      → preferredMaxLayoutWidth == 278(已就位)✅
      → 同步调用 sizeThatFits(width: 278) → 立即算出 3 行的真实高度 61pt
  → topView 高度 = 13 + 61 + 3 + 31 + 13 = 121 ✅

contentView.bounds.width - 40 - 112 中:

  • 40 = bgView 左右各 20pt 的内缩
  • 112 = leftIcon(40) + offset(12) + rightButton(40) + offset(20) 等水平占用

contentView.bounds.widthupdateConstraints 时已经由 table view 赋予了正确宽度(430pt),所以计算有效。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容