根据Swift中的String计算出UILabel的大小

Cod*_*ver 167 string iphone uilabel ios swift3

我试图根据不同的字符串长度计算UILabel的高度.

func calculateContentHeight() -> CGFloat{
    var maxLabelSize: CGSize = CGSizeMake(frame.size.width - 48, CGFloat(9999))
    var contentNSString = contentText as NSString
    var expectedLabelSize = contentNSString.boundingRectWithSize(maxLabelSize, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(16.0)], context: nil)
    print("\(expectedLabelSize)")
    return expectedLabelSize.size.height

}
Run Code Online (Sandbox Code Playgroud)

以上是我用来确定高度但不起作用的当前功能.我非常感谢能得到的任何帮助.我会在Swift中给出答案而不是Objective C.

Kaa*_*glu 478

使用扩展程序 String

斯威夫特3

extension String {
    func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

        return ceil(boundingBox.height)
    }

    func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

        return ceil(boundingBox.width)
    }
}
Run Code Online (Sandbox Code Playgroud)

以及NSAttributedString(有时非常有用)

extension NSAttributedString {
    func height(withConstrainedWidth width: CGFloat) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)

        return ceil(boundingBox.height)
    }

    func width(withConstrainedHeight height: CGFloat) -> CGFloat {
        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)

        return ceil(boundingBox.width)
    }
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特4

只要改变值attributesextension String方法

[NSFontAttributeName: font]
Run Code Online (Sandbox Code Playgroud)

[.font : font]
Run Code Online (Sandbox Code Playgroud)

  • @KaanDedeoglu如何使用动态高度字符串,例如当你使用"numberOfLines"= 0(可能是特定于UILabel,不确定)或lineBreakMode ByWordWrapping时.我的猜测是将它添加到像这样的属性`[NSFontAttributeName:font,NSLineBreakMode:.ByWordWrapping]`但是它不起作用 (7认同)
  • 想我想出了我的答案。我需要使用`NSParagraphStyleAttributeName : style`,其中样式是 NSMutableParagraphStyle (3认同)
  • @CodyWeaver 检查 widthWithConstrainedHeight 方法的编辑。 (2认同)
  • 我需要写“ self.boundingRect”而不是“ boundingRect”,否则会出现编译错误。 (2认同)

Sn0*_*eze 15

对于多行文本,此答案无法正常工作.您可以使用UILabel构建不同的String扩展

extension String {
func height(constraintedWidth width: CGFloat, font: UIFont) -> CGFloat {
    let label =  UILabel(frame: CGRect(x: 0, y: 0, width: width, height: .greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.text = self
    label.font = font
    label.sizeToFit()

    return label.frame.height
 }
}
Run Code Online (Sandbox Code Playgroud)

UILabel获得固定宽度,.numberOfLines设置为0.通过添加文本并调用.sizeToFit(),它会自动调整到正确的高度.

代码是用Swift 3编写的

  • 然而,由于图纸的多次通过,sizeToFit引入了数百万个性能问题.手动计算大小的资源更便宜 (14认同)
  • 此解决方案应设置UILabel的UIFont以确保正确的高度. (2认同)
  • 我发布了一个类似的解决方案——无需调用“sizeToFit” (2认同)

Rya*_*anG 12

这是一个对我有用的简单解决方案......类似于其他一些发布的解决方案,但它不包括调用的需要 sizeToFit

请注意,这是用 Swift 5 编写的

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.font = UIFont.systemFont(ofSize: 12) // make sure you set this correctly 
lbl.text = "My text that may or may not wrap lines..."

let width = 100.0 // the width of the view you are constraint to, keep in mind any applied margins here

let height = lbl.systemLayoutSizeFitting(CGSize(width: width, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height
Run Code Online (Sandbox Code Playgroud)

这处理换行等。不是最优雅的代码,但它完成了工作。

  • 很好的答案!谢谢 (2认同)

iOS*_*iOS 7

这是我在 Swift 4.1 和 Xcode 9.4.1 中的答案

//This is your label
let proNameLbl = UILabel(frame: CGRect(x: 0, y: 20, width: 300, height: height))
proNameLbl.text = "This is your text"
proNameLbl.font = UIFont.systemFont(ofSize: 17)
proNameLbl.numberOfLines = 0
proNameLbl.lineBreakMode = .byWordWrapping
infoView.addSubview(proNameLbl)

//Function to calculate height for label based on text
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat {
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}
Run Code Online (Sandbox Code Playgroud)

现在你调用这个函数

//Call this function
let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300)
print(height)//Output : 41.0
Run Code Online (Sandbox Code Playgroud)


Geo*_*nov 7

斯威夫特5:

如果您有 UILabel,但由于某种原因,boundingRect 不适合您(我遇到了这个问题。它总是返回 1 行高。)有一个扩展可以轻松计算标签大小。

extension UILabel {
    func getSize(constrainedWidth: CGFloat) -> CGSize {
        return systemLayoutSizeFitting(CGSize(width: constrainedWidth, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以这样使用它:

let label = UILabel()
label.text = "My text\nIs\nAwesome"
let labelSize = label.getSize(constrainedWidth:200.0)
Run Code Online (Sandbox Code Playgroud)

对我有用