211

さまざまな文字列の長さに基づいて 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

}

上記は、高さを決定するために使用する現在の関数ですが、機能していません。私が得ることができる助けを大いに感謝します。Objective Cではなく、Swiftでの回答を希望します。

4

12 に答える 12

596

で拡張機能を使用する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)
    }
}

また、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)
    }
}

スイフト 4 & 5

メソッドattributesの値を変更するだけですextension String

から

[NSFontAttributeName: font]

[.font : font]
于 2015-05-26T05:59:13.037 に答える
18

複数行のテキストの場合、この回答は正しく機能していません。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
 }
}

UILabel は固定幅を取得し、.numberOfLines は 0 に設定されます。テキストを追加して .sizeToFit() を呼び出すと、正しい高さに自動的に調整されます。

コードはSwift 3で書かれています

于 2016-11-17T10:41:52.680 に答える
2

受け入れられた回答は固定幅では機能しますが、固定高さでは機能しないことがわかりました。固定の高さの場合、テキストに改行がない限り、幅を広げてすべてを 1 行に収めます。

width 関数は height 関数を複数回呼び出しますが、これは簡単な計算であり、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)
    }
}
于 2019-01-09T16:35:41.383 に答える
-1
@IBOutlet weak var constraintTxtV: NSLayoutConstraint!
func TextViewDynamicallyIncreaseSize() {
    let contentSize = self.txtVDetails.sizeThatFits(self.txtVDetails.bounds.size)
    let higntcons = contentSize.height
    constraintTxtV.constant = higntcons
}
于 2017-11-24T10:07:56.780 に答える