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を作成せずに、必要に応じてサイズを計算するためのメソッドがあります。
ウラジミールグリツェンコ2014

@VladimirGritsenko 'sizeWithFont'メソッドはSwiftでは使用できません:(
TheBurgerShot

私はSwiftの専門家ではないことは認めますが、独自のブリッジ方法を追加できると思います。サイズを計算するためにUILabelを作成するよりも価値があります。
Vladimir Gritsenko 2014

@TheBurgerShot sizeWithFontはSwift Stringでは使用できない場合がありますが、Swift では使用できますNSString。その上で呼び出すことはできます。
Anorak 2014

結局、エラーは何か別のものであり、このメソッドとは何の関係もありませんでした。これはまだ他の人に役立つかもしれませんが。
TheBurgerShot 2015年

回答:


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、2015

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

ビューコントローラーでこの関数を呼び出すことができません...考えられる理由を教えていただけますか?
Rouny

64

AutoLayoutを使用している場合は、構成UILabelUIのみで高さを調整できます。

iOS8以降の場合

  • 制約の先頭/末尾を設定します UILabel
  • の行をUILabel1から0に変更します

ここに画像の説明を入力してください

iOS7の場合

  • 最初にを含む高さを追加する必要がありますUILabel
  • 次に、リレーションをからEqualに変更しますGreater than or Equal

ここに画像の説明を入力してください

  • 最後に、行をUILabel1から0 に変更します

ここに画像の説明を入力してください

あなたUILabelはテキストに応じて自動的に高さを増やします


2
ラベルがセル内にある場合。それに応じて、いつどのようにセルの高さを増やしますか?
oyalhi

1
@oyalhi、あなたのラベルがテーブルビューのセル内にある場合は、私の他のポストを参照してくださいstackoverflow.com/a/36277840/5381331を
ファンティエットヴァンたLiNH

3
これは完璧に機能しました!制約を設定すると、正しく機能します!
Bill Thompson

2
UILabelで「Label」という単語を使用すると、height = 20になります。この設定後も20のままです。
gadget00 2016年

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 2016

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

UILabelの拡張機能の計算されたプロパティとしてAnorakによって提案されたソリューション:

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'は取得専用のプロパティです。
Amg91 2018

4

@Anorakの回答に続いて、この拡張をStringに追加し、インセットをパラメーターとして送信しました。これは、多くの場合、テキストにパディングが必要になるためです。とにかく、多分あなたはこれが便利だと思うでしょう。

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でテキストの高さを計算する方法は次のとおりです。次に、四角形から高さを取得し、ラベルや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

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

ブロック引用NSParagraphStyle.LineBreakModeは、段落内の単語ではなく段落全体に適用されます。このプロパティは、通常の描画時と、境界ボックス内のラベルのテキストに合わせてフォントサイズを小さくする必要がある場合の両方で有効です。このプロパティは、デフォルトでbyTruncatingTailに設定されています。

このリンクは、同じことを行うストーリーボードの方法を説明しています


2
コードのみの回答は良い習慣とは見なされません。回答が質問にどのように対処するかについての説明を追加することを検討してください。
Yannis 2017

2

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

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を選択し、サイズインスペクター(ルーラーアイコン)に移動します。3)ラベルと相互作用している他のすべてのUIView(ラベル、ボタン、画像ビューなど)コンポーネントの[コンテンツの圧縮抵抗の優先度を1に]に移動します。

たとえば、ビューにUIImageView、タイトルラベル、説明ラベルが縦に並んでいます。Content Compression Resistance PriorityをUIImageViewに設定し、titleラベルを1に、descriptionラベルを750に設定しました。これにより、descriptionラベルは必要な高さになります。


0

迅速にラベルを動的にするには、高さ制限を指定せず、ストーリーボードでラベルの行数を0に設定すると、下部の制約も与えられます。これは、コンテンツサイズに従って動的ラベルを処理する最良の方法です。


0

sizeThatFits関数を使用することもできます。

例えば:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.