Figure out size of UILabel based on String in Swift

后端 未结 11 1417
执笔经年
执笔经年 2020-11-22 13:35

I am trying to calculate the height of a UILabel based on different String lengths.

func calculateContentHeight() -> CGFloat{
    var maxLabelSize: CGSize         


        
相关标签:
11条回答
  • 2020-11-22 14:27

    This is my answer in Swift 4.1 and 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
    }
    

    Now you call this function

    //Call this function
    let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300)
    print(height)//Output : 41.0
    
    0 讨论(0)
  • 2020-11-22 14:28

    For multiline text this answer is not working correctly. You can build a different String extension by using UILabel

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

    The UILabel gets a fixed width and the .numberOfLines is set to 0. By adding the text and calling .sizeToFit() it automatically adjusts to the correct height.

    Code is written in Swift 3

    0 讨论(0)
  • 2020-11-22 14:28

    Check label text height and it is working on it

    let labelTextSize = ((labelDescription.text)! as NSString).boundingRect(
                    with: CGSize(width: labelDescription.frame.width, height: .greatestFiniteMagnitude),
                    options: .usesLineFragmentOrigin,
                    attributes: [.font: labelDescription.font],
                    context: nil).size
                if labelTextSize.height > labelDescription.bounds.height {
                    viewMoreOrLess.hide(byHeight: false)
                    viewLess.hide(byHeight: false)
                }
                else {
                    viewMoreOrLess.hide(byHeight: true)
                    viewLess.hide(byHeight: true)
    
                }
    
    0 讨论(0)
  • 2020-11-22 14:36

    I found that the accepted answer worked for a fixed width, but not a fixed height. For a fixed height, it would just increase the width to fit everything on one line, unless there was a line break in the text.

    The width function calls the height function multiple times, but it is a quick calculation and I didn't notice performance issues using the function in the rows of a UITable.

    extension String {
    
        public func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
            let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
            let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font : font], context: nil)
    
            return ceil(boundingBox.height)
        }
    
        public func width(withConstrainedHeight height: CGFloat, font: UIFont, minimumTextWrapWidth:CGFloat) -> CGFloat {
    
            var textWidth:CGFloat = minimumTextWrapWidth
            let incrementWidth:CGFloat = minimumTextWrapWidth * 0.1
            var textHeight:CGFloat = self.height(withConstrainedWidth: textWidth, font: font)
    
            //Increase width by 10% of minimumTextWrapWidth until minimum width found that makes the text fit within the specified height
            while textHeight > height {
                textWidth += incrementWidth
                textHeight = self.height(withConstrainedWidth: textWidth, font: font)
            }
            return ceil(textWidth)
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:40

    Use an extension on String

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

    and also on NSAttributedString (which is very useful at times)

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

    Swift 4

    Just change the value for attributes in the extension String methods

    from

    [NSFontAttributeName: font]
    

    to

    [.font : font]
    
    0 讨论(0)
提交回复
热议问题