如何动态计算带有行间距的NSAttributedString的高度

4

我正在尝试计算具有LineSpacing属性的UILabel的高度。奇怪的是,正常label.text的计算高度小于label.attributedText与其行高的高度。看起来我做错了什么,但找不到原因,请帮忙 :D。

提供的代码是为了使其紧凑和清晰而专门制作的,它在我的项目中实现方式不同。

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时,它无法计算出正确的值。
2个回答

4
您可以使用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
    }

谢谢,我不知道SizeThatFits()是这样工作的 :). 我会更新我的扩展程序,使用SizeThatFits()设置行高并返回所需的uilabel高度。 - MQoder

0

我这样更新了我的扩展程序,以设置行高并同时返回新标签的高度。感谢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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接