NSAttributedString boundingRect returns 高度错误
NSAttributedString boundingRect returns wrong height
我这样计算一个NSAttributedString
的高度。
let maxSize = NSSize(width: w, height: CGFloat.greatestFiniteMagnitude)
let rect = boundingRect(with: maxSize, options: [.usesFontLeading, .usesLineFragmentOrigin])
let height = rect.integral.size.height
我尝试了 SO 中提到的每一个 "hack",但是宽度越小,字符串高度就越不准确(计算的高度大于实际高度)。
根据其他帖子,以下情况会导致尺寸计算出现问题:
- 空格
- 无前景色
- 无背景色
- 宽度低于 300 不起作用 (?)
我发现 none 这些建议有任何不同。属性字符串是多行的串联,每行都有一个 foregroundColor
和 backgroundColor
。字符串还有如下段落样式。
let pstyle = NSMutableParagraphStyle()
pstyle.lineSpacing = 6
pstyle.lineBreakMode = .byWordWrapping
和尺寸为 11 的 userFixedPitchFont
。
为什么宽度越小高度误差越大?
PS:我想这与lineBreak
有关,因为如果换行的行越多,错误就会越大。
我发现此解决方案有效。请注意,如果您不将 lineFragmentPadding
设置为 0
,它会产生与 boundingRect
.
相同(错误)的结果
extension NSAttributedString {
func sizeFittingWidth(_ w: CGFloat) -> CGSize {
let textStorage = NSTextStorage(attributedString: self)
let size = CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)
let boundingRect = CGRect(origin: .zero, size: size)
let textContainer = NSTextContainer(size: size)
textContainer.lineFragmentPadding = 0
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
layoutManager.glyphRange(forBoundingRect: boundingRect, in: textContainer)
let rect = layoutManager.usedRect(for: textContainer)
return rect.integral.size
}
}
我这样计算一个NSAttributedString
的高度。
let maxSize = NSSize(width: w, height: CGFloat.greatestFiniteMagnitude)
let rect = boundingRect(with: maxSize, options: [.usesFontLeading, .usesLineFragmentOrigin])
let height = rect.integral.size.height
我尝试了 SO 中提到的每一个 "hack",但是宽度越小,字符串高度就越不准确(计算的高度大于实际高度)。
根据其他帖子,以下情况会导致尺寸计算出现问题:
- 空格
- 无前景色
- 无背景色
- 宽度低于 300 不起作用 (?)
我发现 none 这些建议有任何不同。属性字符串是多行的串联,每行都有一个 foregroundColor
和 backgroundColor
。字符串还有如下段落样式。
let pstyle = NSMutableParagraphStyle()
pstyle.lineSpacing = 6
pstyle.lineBreakMode = .byWordWrapping
和尺寸为 11 的 userFixedPitchFont
。
为什么宽度越小高度误差越大?
PS:我想这与lineBreak
有关,因为如果换行的行越多,错误就会越大。
我发现此解决方案有效。请注意,如果您不将 lineFragmentPadding
设置为 0
,它会产生与 boundingRect
.
extension NSAttributedString {
func sizeFittingWidth(_ w: CGFloat) -> CGSize {
let textStorage = NSTextStorage(attributedString: self)
let size = CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)
let boundingRect = CGRect(origin: .zero, size: size)
let textContainer = NSTextContainer(size: size)
textContainer.lineFragmentPadding = 0
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
layoutManager.glyphRange(forBoundingRect: boundingRect, in: textContainer)
let rect = layoutManager.usedRect(for: textContainer)
return rect.integral.size
}
}