如何动态计算具有行间距的nsattributed字符串的高度
How to calculate height of nsattributed string with line spacing dynamically
我正在尝试计算具有 LineSpacing 属性的 UILabel 的高度。奇怪的是,正常 label.text 的高度计算值低于 label.attributedText 及其行高。看起来我做错了什么,但找不到什么,所以请帮忙:D.
提供的代码是专门为SO编写的,简洁明了,在我的项目中实现不同。
extension NSAttributedString {
func heightWithWidth(width: CGFloat) -> CGFloat {
let maxSize = CGSize(width: width, height: CGFloat.max)
let boundingBox = self.boundingRectWithSize(maxSize, options: [.UsesLineFragmentOrigin, .UsesFontLeading, .UsesDeviceMetrics], context: nil)
return boundingBox.height
}
}
extension UILabel {
func getHeightWithGivenWidthAndLineHeight(lineHeight: CGFloat, labelWidth: CGFloat) -> CGFloat {
let text = self.text
if let text = text {
let attributeString = NSMutableAttributedString(string: text)
let style = NSMutableParagraphStyle()
style.lineSpacing = lineHeight
attributeString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSMakeRange(0, text.characters.count))
let height = attributeString.heightWithWidth(labelWidth)
self.attributedText = attributeString
return height
}
return 0
}
我称之为
let contentHeight = contentLabel.text! == "" ? 0 : contentLabel.getHeightWithGivenWidthAndLineHeight(3, labelWidth: labelWidth)
使用普通字符串(无间距)效果很好,当我将 attributedstring 与 lineSpacing 一起使用时,它无法计算出正确的值。
您可以只使用 UILabel 的 sizeThatFits。例如:
let text = "This is\nSome\nGreat\nText"
let contentHeight = contentLabel.text! == "" ? 0 : contentLabel.getHeightWidthGivenWidthAndLineHeight(6, labelWidth: labelWidth)
//returns 73.2
但只是设置
contentLabel.attributedText = contentLabel.attributedString //attributedString is same as getHeightWidthGivenWidthAndLineHeight
let size = contentLabel.sizeThatFits(contentLabel.frame.size)
//returns (w 49.5,h 99.5)
已添加到您的扩展中的 attributedString 代码,如果您需要查看:
var attributedString:NSAttributedString?{
if let text = self.text{
let attributeString = NSMutableAttributedString(string: text)
let style = NSMutableParagraphStyle()
style.lineSpacing = 6
attributeString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSMakeRange(0, text.characters.count))
return attributeString
}
return nil
}
我以这种方式更新了我的扩展,以同时设置行高和 return 新标签高度。感谢 beyowulf
extension UILabel {
func setLineHeight(lineHeight: CGFloat, labelWidth: CGFloat) -> CGFloat {
let text = self.text
if let text = text {
let attributeString = NSMutableAttributedString(string: text)
let style = NSMutableParagraphStyle()
style.lineSpacing = lineHeight
attributeString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSMakeRange(0, text.characters.count))
self.attributedText = attributeString
return self.sizeThatFits(CGSize(width: labelWidth, height: 20)).height
}
return 0
}
}
我正在尝试计算具有 LineSpacing 属性的 UILabel 的高度。奇怪的是,正常 label.text 的高度计算值低于 label.attributedText 及其行高。看起来我做错了什么,但找不到什么,所以请帮忙:D.
提供的代码是专门为SO编写的,简洁明了,在我的项目中实现不同。
extension NSAttributedString {
func heightWithWidth(width: CGFloat) -> CGFloat {
let maxSize = CGSize(width: width, height: CGFloat.max)
let boundingBox = self.boundingRectWithSize(maxSize, options: [.UsesLineFragmentOrigin, .UsesFontLeading, .UsesDeviceMetrics], context: nil)
return boundingBox.height
}
}
extension UILabel {
func getHeightWithGivenWidthAndLineHeight(lineHeight: CGFloat, labelWidth: CGFloat) -> CGFloat {
let text = self.text
if let text = text {
let attributeString = NSMutableAttributedString(string: text)
let style = NSMutableParagraphStyle()
style.lineSpacing = lineHeight
attributeString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSMakeRange(0, text.characters.count))
let height = attributeString.heightWithWidth(labelWidth)
self.attributedText = attributeString
return height
}
return 0
}
我称之为
let contentHeight = contentLabel.text! == "" ? 0 : contentLabel.getHeightWithGivenWidthAndLineHeight(3, labelWidth: labelWidth)
使用普通字符串(无间距)效果很好,当我将 attributedstring 与 lineSpacing 一起使用时,它无法计算出正确的值。
您可以只使用 UILabel 的 sizeThatFits。例如:
let text = "This is\nSome\nGreat\nText"
let contentHeight = contentLabel.text! == "" ? 0 : contentLabel.getHeightWidthGivenWidthAndLineHeight(6, labelWidth: labelWidth)
//returns 73.2
但只是设置
contentLabel.attributedText = contentLabel.attributedString //attributedString is same as getHeightWidthGivenWidthAndLineHeight
let size = contentLabel.sizeThatFits(contentLabel.frame.size)
//returns (w 49.5,h 99.5)
已添加到您的扩展中的 attributedString 代码,如果您需要查看:
var attributedString:NSAttributedString?{
if let text = self.text{
let attributeString = NSMutableAttributedString(string: text)
let style = NSMutableParagraphStyle()
style.lineSpacing = 6
attributeString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSMakeRange(0, text.characters.count))
return attributeString
}
return nil
}
我以这种方式更新了我的扩展,以同时设置行高和 return 新标签高度。感谢 beyowulf
extension UILabel {
func setLineHeight(lineHeight: CGFloat, labelWidth: CGFloat) -> CGFloat {
let text = self.text
if let text = text {
let attributeString = NSMutableAttributedString(string: text)
let style = NSMutableParagraphStyle()
style.lineSpacing = lineHeight
attributeString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSMakeRange(0, text.characters.count))
self.attributedText = attributeString
return self.sizeThatFits(CGSize(width: labelWidth, height: 20)).height
}
return 0
}
}