【问题标题】:Adjust UILabel height to text将 UILabel 高度调整为文本
【发布时间】:2014-09-30 13:44:27
【问题描述】:

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

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。
  • @VladimirGritsenko 'sizeWithFont' 方法在 Swift 中不可用:(
  • 我承认我不是 Swift 专家,但我相信您可以添加自己的桥接方法。仍然值得创建 UILabel 来计算大小。
  • @TheBurgerShot sizeWithFont 可能不适用于 Swift String 但它可以在 NSString 上使用,您应该仍然可以调用它。
  • 最后,错误是不同的,与此方法无关。虽然这可能对其他人仍然有帮助。

标签: ios swift height uilabel frame


【解决方案1】:

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

为 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
}

【讨论】:

  • 这在操场上也适用于 mee,错误似乎不会发生在这个特定的地方,当我删除这种方法的用法时,它会抱怨一些 println 或只是一行cmets(然后它也显示 EXC_BAD_ACCESS code=2)
  • 它在操场上工作,但在 XCode 6.1 中的视图控制器内部没有按需要进行大小调整
  • 我有点犹豫是否要根据尺寸创建一个新的UILabel;如果在 layoutSubviews 内部使用此方法,并且在每个完整布局中可能会被多次调用,则额外的对象创建可能会引入明显的延迟,尤其是在滚动期间。
  • 让 textRect = textString.boundingRectWithSize(CGSizeMake(320, 2000),选项:.UsesLineFragmentOrigin,属性:textAttributes,上下文:nil)
  • 我无法在我的视图控制器中调用这个函数...你能告诉我可能的原因吗?
【解决方案2】:

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

在布局子视图中:

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

【讨论】:

  • 证明..谢谢!
【解决方案3】:

只需设置:

label.numberOfLines = 0

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

【讨论】:

  • 这不会使 UILabel 调整它的高度。
【解决方案4】:

如果你愿意,我会创建这个扩展

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

【讨论】:

    【解决方案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
    

    【讨论】:

    • 无法分配给属性:'height' 是一个 get-only 属性。
    【解决方案6】:

    这是在 Swift 中计算文本高度的方法。然后可以从rect中获取高度,设置label或者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)
    

    【讨论】:

      【解决方案7】:

      在@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 这行对我有帮助,谢谢。
      【解决方案8】:

      在需要动态标签高度的地方调用这个方法

      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
      }
      

      【讨论】:

        【解决方案9】:

        如果您使用 AutoLayout,您只能通过配置 UI 调整 UILabel 高度。

        适用于 iOS8 或更高版本

        • 为您的UILabel 设置约束前导/尾随
        • 并将UILabel的行从1改为0

        适用于 iOS7

        • 首先,你需要为UILabel添加包含高度
        • 然后,将Relation从Equal修改为Greater than or Equal

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

        您的UILabel 会根据文字自动增加高度

        【讨论】:

        • 如果标签在单元格内。何时以及如何相应地增加单元格高度?
        • @oyalhi,如果您的标签在 tableview 单元格内,请参阅我的另一篇帖子 stackoverflow.com/a/36277840/5381331
        • 这对我来说非常有效!设置约束,它将正常工作!
        • 不适合我...UILabel 中的“标签”一词使高度=20。此设置后仍为 20。
        • 不知道“添加包含 UILabel 的高度”是什么意思,并且 UIBuilder 中没有第一项(如图)的“高度约束”部分??
        【解决方案10】:

        基于 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
        }
        

        【讨论】:

          【解决方案11】:

          Swift 4.0

          self.messageLabel = UILabel(frame: CGRect(x: 70, y: 60, width:UIScreen.main.bounds.width - 80, height: 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。

          This link describes the storyboard way of doing the same

          【讨论】:

          • 纯代码答案不被认为是好的做法。请考虑添加一些关于您的答案如何解决问题的解释。
          【解决方案12】:

          Swift 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()
             }
          }
          

          【讨论】:

            【解决方案13】:

            Swift 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
                }
            
            }
            

            【讨论】:

              【解决方案14】:

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

              【讨论】:

                【解决方案15】:

                要在 swift 中使标签动态化,不要给出高度约束,并且在情节提要中使标签行数 0 也给出底部约束,这是我根据内容大小处理动态标签的最佳方式。

                【讨论】:

                  【解决方案16】:

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

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

                  2) 从情节提要中选择您的 UILabel 并转到 Size Inspector(标尺图标), 3) 对于与您的标签交互的所有其他 UIView(标签、按钮、图像视图等)组件,转到“内容压缩阻力优先级为 1”。

                  例如,我的视图中有 UIImageView、标题标签和描述标签。我将内容压缩阻力优先级设置为 UIImageView,将标题标签设置为 1,将描述标签设置为 750。这将使描述标签具有所需的高度。

                  【讨论】:

                    【解决方案17】:

                    你也可以使用sizeThatFits函数。

                    例如:

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

                    【讨论】:

                      猜你喜欢
                      • 2010-10-01
                      • 2020-06-06
                      • 1970-01-01
                      • 2014-11-28
                      • 2015-01-28
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多