将UILabel高度调整为文本


112

我有一些标签要根据文本调整高度,这是我现在为此编写的代码

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.ByWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}

编辑:

问题不在这段代码中,所以我的解决方法是问题本身。它可能对其他人仍然有用!


看一下NSString UIKit的添加,那里有一些方法可以根据需要计算大小而无需创建UILabel。
弗拉基米尔·格里申科(Fladimir Gritsenko)2014年

@VladimirGritsenko'sizeWithFont'方法在Swift中不可用:(
TheBurgerShot

我承认我不是Swift方面的专家,但我相信您可以添加自己的桥接方法。创建UILabel来计算大小仍然值得。
弗拉基米尔·格里申科(Fladimir Gritsenko)2014年

@TheBurgerShot sizeWithFont可能不适用于Swift,String但是它可以在Swift 上使用。NSString您仍然应该能够在其上调用它。
Anorak 2014年

最后,错误有所不同,并且与该方法无关。虽然这可能对其他人还是有帮助的。
TheBurgerShot 2015年

Answers:


189

我刚把它放在操场上,对我有用。

为Swift 4.0更新

import UIKit

 func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}

let font = UIFont(name: "Helvetica", size: 20.0)

var height = heightForView("This is just a load of text", font: font, width: 100.0)

斯威夫特3:

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
}

在此处输入图片说明


这在操场上也很适合我,在该特定位置似乎没有发生错误,当我删除此方法的用法时,它会抱怨一些println或仅带有注释的一行(然后它说EXC_BAD_ACCESS code = 2也是如此)
TheBurgerShot 2014年

6
它可以在操场上工作,但是不会在XCode 6.1
Unome

1
我有点犹豫要创建一个新的UILabel大小调整;如果在内部layoutSubviews使用此方法并倾向于在每个完整布局中多次调用,则额外的对象创建可能会引入明显的延迟,尤其是在滚动过程中。
Zorayr

让textRect = textString.boundingRectWithSize(CGSizeMake(320,2000),选项:.UsesLineFragmentOrigin,属性:textAttributes,上下文:nil)
Siddharth Pancholi

我无法在视图控制器中调用此函数...您能建议我可能是什么原因吗?
鲁尼

64

如果您使用的是AutoLayout,则UILabel只能通过config UI 调整高度。

适用于iOS8或更高版本

  • 为您设置约束条件领先/追踪 UILabel
  • 并将行UILabel从1 更改为0

在此处输入图片说明

对于iOS7

  • 首先,您需要添加包含高度UILabel
  • 然后,将关系从修改EqualGreater than or Equal

在此处输入图片说明

  • 最后,将行UILabel从1 更改为0

在此处输入图片说明

UILabel将根据文本自动增加高度


2
并且如果标签在单元格内。您何时以及如何相应地增加像元高度?
oyalhi

1
@oyalhi,如果您的标签位于表格视图单元格中,请参阅我的另一篇文章stackoverflow.com/a/36277840/5381331
Phan Van Linh

3
这对我来说很完美!设置约束,它将正常工作!
比尔·汤普森

2
不适用于我... UILabel中的“标签”一词使height = 20。设置后仍为20。
gadget00

9

我可以创建此扩展

extension UILabel {
    func setSizeFont (sizeFont: CGFloat) {
        self.font =  UIFont(name: self.font.fontName, size: sizeFont)!
        self.sizeToFit()
    }
}

8

我有很强的工作解决方案。

在layoutSubviews中:

    _title.frame = CGRect(x: 0, y: 0, width: bounds.width, height: 0)
    _title.sizeToFit()
    _title.frame.size = _title.bounds.size

在文本设置器中:

    _title.text = newValue
    setNeedsLayout()

UPD。 当然可以使用以下UILabel设置:

    _title.lineBreakMode = .ByWordWrapping
    _title.numberOfLines = 0

6

只需设置:

label.numberOfLines = 0

标签会根据输入的文本量自动调整其高度。


27
这不会使UILabel调整其高度。
TheBurgerShot

6

基于Anorak的答案,我也同意Zorayr的担心,因此我添加了几行内容以删除UILabel并仅返回CGFloat,我不知道这是否有帮助,因为原始代码未添加UIabel,但是它不会引发错误,因此我正在使用以下代码:

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{

    var currHeight:CGFloat!

    let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.ByWordWrapping
    label.font = font
    label.text = text
    label.sizeToFit()

    currHeight = label.frame.height
    label.removeFromSuperview()

    return currHeight
}

5

在Swift 4.1和Xcode 9.4.1中

3步

第1步)

//To calculate height for label based on text size and width
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
}

第2步)

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

步骤3)

//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)

5

Anorak建议的解决方案是UILabel扩展中的计算属性:

extension UILabel
{
var optimalHeight : CGFloat
    {
        get
        {
            let label = UILabel(frame: CGRectMake(0, 0, self.frame.width, CGFloat.max))
            label.numberOfLines = 0
            label.lineBreakMode = self.lineBreakMode
            label.font = self.font
            label.text = self.text

            label.sizeToFit()

            return label.frame.height
         }
    }
}

用法:

self.brandModelLabel.frame.size.height = self.brandModelLabel.optimalHeight

不错的解决方案!谢谢您:-)
Cristina

无法分配给属性:“ height”是仅获取属性。
Amg91

4

在@Anorak答案之后,我将此扩展名添加到String并发送了一个inset作为参数,因为很多时候您将需要对文本进行填充。无论如何,也许您会发现一些有用的东西。

extension String {

    func heightForWithFont(font: UIFont, width: CGFloat, insets: UIEdgeInsets) -> CGFloat {

        let label:UILabel = UILabel(frame: CGRectMake(0, 0, width + insets.left + insets.right, CGFloat.max))
        label.numberOfLines = 0
        label.lineBreakMode = NSLineBreakMode.ByWordWrapping
        label.font = font
        label.text = self

        label.sizeToFit()
        return label.frame.height + insets.top + insets.bottom
    }
}

label.lineBreakMode = NSLineBreakMode.ByWordWrapping这行帮助了我。
Coder_A_D

3

这是在Swift中计算文字高度的方法。然后,您可以从rect获取高度,并设置标签或textView等的约束高度。

let font = UIFont(name: "HelveticaNeue", size: 25)!
let text = "This is some really long text just to test how it works for calculating heights in swift of string sizes. What if I add a couple lines of text?"

let textString = text as NSString

let textAttributes = [NSFontAttributeName: font]

let textRect = textString.boundingRectWithSize(CGSizeMake(320, 2000), options: .UsesLineFragmentOrigin, attributes: textAttributes, context: nil)

3

只需在需要动态高度标签的地方调用此方法

func getHeightforController(view: AnyObject) -> CGFloat {
    let tempView: UILabel = view as! UILabel
    var context: NSStringDrawingContext = NSStringDrawingContext()
    context.minimumScaleFactor = 0.8

    var width: CGFloat = tempView.frame.size.width

    width = ((UIScreen.mainScreen().bounds.width)/320)*width

    let size: CGSize = tempView.text!.boundingRectWithSize(CGSizeMake(width, 2000), options:NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: tempView.font], context: context).size as CGSize

    return size.height
}

3

迅捷4.0

self.messageLabel = UILabel(框架:CGRect(x:70,y:60,宽度:UIScreen.main.bounds.width-80,高度:30)

messageLabel.text = message

messageLabel.lineBreakMode = .byWordWrapping //in versions below swift 3 (messageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping)    
messageLabel.numberOfLines = 0 //To write any number of lines within a label scope

messageLabel.textAlignment = .center

messageLabel.textColor = UIColor.white

messageLabel.font = messageLabel.font.withSize(12)

messageLabel.sizeToFit()

Blockquote NSParagraphStyle.LineBreakMode,适用于整个段落,而不适用于段落中的单词。此属性在正常绘图期间以及在必须减小字体大小以使其标签文本适合其边框时有效。默认情况下,此属性设置为byTruncatingTail。

此链接描述情节提要的相同方法


2
仅代码答案不被视为良好实践。请考虑添加一些有关您的答案如何解决该问题的解释。
亚尼斯,

2

迅捷4.0

代替计算文本/标签的高度,我只是在插入(动态)文本后调整标签的大小。

假设myLabel是有问题的UILabel:

let myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: *somewidth*, height: *placeholder, e.g. 20*))
myLabel.numberOfLines = 0
myLabel.lineBreakMode = .byWordWrapping
...

现在来了有趣的部分:

var myLabelText: String = "" {
   didSet {
      myLabel.text = myLabelText
      myLabel.sizeToFit()
   }
}

2

雨燕4.1的扩展方法来计算标签高度:

extension UILabel {

    func heightForLabel(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
    }

}

1

Swift 5,XCode 11情节提要方式。我认为这适用于iOS 9及更高版本。例如,您想要“描述”标签来获取动态高度,请按照以下步骤操作:

1)选择描述标签->转到属性检查器(铅笔图标),设置:行:0换行符:自动换行

2)从情节提要中选择您的UILabel,然后转到Size Inspector(大小图标),3)转到“与标签交互的所有其他UIView(标签,按钮,imageview等)组件的“内容压缩优先级为1”。

例如,我在视图中垂直具有UIImageView,Title标签和Description标签。我将“内容抗压缩优先级”设置为UIImageView,并将标题标签设置为1,并将描述标签设置为750。这将使描述标签占据所需高度。



0

您也可以使用sizeThatFits功能。

例如:

label.sizeThatFits(superView.frame.size).height

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.