UILabelは、ラベルサイズに合わせてテキストを自動縮小しません


119

私はこの奇妙な問題を抱えており、8時間以上処理しています。状況に応じてUILabels、動的にサイズを計算する必要があります。
たとえば
UIViewControllerイベントを受け取ってUILabelsサイズを変更します。大きいものから小さいものへ。私のサイズUILabelは小さくなり、適切な必要なサイズが得られますが、私のテキストUILabelは同じまま、同じフォントサイズなどUILabelです。テキスト全体がに収まるように、フォントを小さくする必要があります。だから問題は、私のラベルに合うようにテキストを作成する方法autoshrinkingですか?

xibUILabels autoshrinkは、チェックされており、行数も0に設定されており、文字列には新しい行記号(\ n)があり、linebreakmodeを選択してwordwrap。多分誰かが今と同じ状況にいて、私を助けることができましたか?本当にありがたいです。

前もって感謝します!

編集: UILabel最小フォントサイズは10に設定されています


設定するラベルのフォントの最小サイズはいくつですか。追加してください。
AJPatel

回答:


159

あなたがまだより良い解決策を探しているなら、私はこれがあなたが望むものだと思います:

タイトル文字列をラベルの境界の四角形に合わせるためにフォントサイズを縮小する必要があるかどうかを示すブール値(このプロパティは、numberOfLinesプロパティが1に設定されている場合にのみ有効です)。

このプロパティを設定するときは、設定するminimumScaleFactor必要があります(適切なデフォルトは0.5です)。

迅速

var adjustsFontSizeToFitWidth: Bool { get set }

Objective-C

@property(nonatomic) BOOL adjustsFontSizeToFitWidth;

文字間の間隔を調整して、ラベルの境界の長方形内の文字列に合わせる必要があるかどうかを示すブール値。

迅速

var allowsDefaultTighteningForTruncation: Bool { get set }

Objective-C

@property(nonatomic) BOOL allowsDefaultTighteningForTruncation;

ソース


18
補足として、minimumFontSizeiOS 6.0 では非推奨です。minimumScaleFactor代わりに使用してください。
レスター

14
はい、自動縮小はUILabelの複数行では機能しません。これを想像してみてください。複数行のテキストがあり、幅に「合う」ように縮小したいとします。それで、テキスト全体を1行に収まるように縮小する必要がありますか、それとも単語は同じ行に留まり、各幅に収まるように縮小する必要がありますか?後者が最も一般的なケースですが、単語も複数行に配置されるように設定されていることを忘れないでください。テキストの自動配置が無効になっている場合でも、すべての単語が幅に収まるわけではないため、異なるフォントサイズのテキストの各行に直面する必要があります。
12

2
私はここのカテゴリでのこの答えは非常に良いと思います、それはあなたがとにかく実装したものであるかもしれません。これは間違いなくApple APIに欠けているものです。あるいは、複数行の静的テキストの一般的な使用例として、縮小が見られないだけかもしれません。
レスター、

1
ええ、それは良い点ですが、とにかく、行数を0に設定すると、1行以上になる可能性があるという明確なステートメントになります。そして、自動縮小は、私が推測する行番号によって決定できる可能性があります。しかし、とにかく、物事を片付けてくれてありがとう。私は何か間違ったことをしていると思った。カテゴリーはいい考えです。これが必要になる他のプロジェクトでこれを行うつもりです。ご協力ありがとうございます。幸運を祈ります;)
Lukas

4
@lester現在のサイズを指定すると、ラベルに対して宣言された行数でテキスト全体が見えるように縮小されます。各行を異なるサイズにする必要はありません。これを理解できないことに本当に驚いています。したがって、表示する(潜在的に)長い文字列がある場合、両方ではなく、複数行にするか、自動サイズにすることができます。可愛いね。
devios1 2013年

125

これはAutoshrink、iOS 9.2、Xcode 7.2でUILabelを機能させる方法(特に6s Plusストーリーボードから4sデバイスのラベルフォントフィッティングの高さ)です...

enter image description here

  • 行数は0です
  • 改行:クリップ
  • 自動縮小:最小フォントスケール0.25

15
これらは、ラベルが実際に収縮するために必要な3つの材料です。クリップの改行設定がありませんでした。また、他のラベルに隣接している場合(これも自動縮小される可能性があります)、圧縮/ハグの優先順位を設定するか、幅または高さの制約を明示的に指定する必要があります。これは、現在受け入れられている答えです。
Korey Hinton、2015

3
行数は私のためにそれをしました!ありがとう
Michael

ラベルにすべての制約、特に先頭と末尾の制約があることを確認してください。
マシャディ

2
Xcode8で同じオプションを試してみましたが、機能していません。これについて誰かがアイデアを持っているなら、私を助けてください。
ガネーシュ

75

minimumFontSize iOS 6では非推奨です。

したがって、のminimumScaleFactor代わりに使用してくださいminmimumFontSize

lbl.adjustsFontSizeToFitWidth = YES
lbl.minimumScaleFactor = 0.5

スウィフト5

lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5

よく答えました。私の問題を解決しました。ありがとう
Abdul Yasin 2014

1
@AntonMatosov、いや、それはしません!
ユリアヌスオノフレイ

2
はい、あります(現在)-改行もワードラップではなくTruncate Tailに設定した場合
TheEye

21

また、私の解決策はブールlabel.adjustsFontSizeToFitWidth = YESです。だが。インターフェイスビルダーで、ワードラップスイッチを「CLIP」に切り替える必要があります。次に、ラベルを自動縮小します。これは非常に重要です。


3
「ワードラップ」から「クリップ」に変更したときのみ、自動縮小が機能しました。
NicJ 2015

ワードラップをクリップに変更すると、実際には行がゼロのラベルでサイズを変更できました。これが文書化されていればいいのですが。
DesignatedNerd

12

Swift 3では(プログラム的に)これを行わなければなりませんでした:

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)

5

次のように書くことができます

UILabel *reviews = [[UILabel alloc]initWithFrame:CGRectMake(14, 13,270,30)];//Set frame
reviews.numberOfLines=0;
reviews.textAlignment = UITextAlignmentLeft;
reviews.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:12];
reviews.textColor=[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.8]; 
reviews.backgroundColor=[UIColor clearColor];

そのような行数を計算できます

CGSize maxlblSize = CGSizeMake(270,9999);
CGSize totalSize = [reviews.text sizeWithFont:reviews.font 
              constrainedToSize:maxlblSize lineBreakMode:reviews.lineBreakMode];

CGRect newFrame =reviews.frame;
newFrame.size.height = totalSize.height;
reviews.frame = newFrame;

CGFloat reviewlblheight = totalSize.height;

int lines=reviewlblheight/12;//12 is the font size of label

UILabel *lbl=[[UILabel alloc]init];
lbl.frame=CGRectMake(140,220 , 100, 25);//set frame as your requirement
lbl.font=[UIFont fontWithName:@"Arial" size:20];
[lbl setAutoresizingMask:UIViewContentModeScaleAspectFill];
[lbl setLineBreakMode:UILineBreakModeClip];
lbl.adjustsFontSizeToFitWidth=YES;//This is main for shrinking font
lbl.text=@"HelloHelloHello";

これがあなたの助けになることを願っています:-)あなたの返信を待っています


ラベルに行数を設定すると、テキストは自動縮小されますか?
Lukas

コンテンツが幅を超えている場合は、次の行に移動します
Birju

ねえあなたが提案したように私はやったが、それはうまくいきません、なぜ行数が私を助けますか?
Lukas 2012年

あなたは正しい、私は役に立たないことを試しましたが、あなたのための解決策を見つけました私の次の答え
Birju

lbl.adjustsFontSizeToFitWidth = YES; 私のために働いた!
開発者

4

結局のところ、私は私の答えを見つけることができませんでした。そして、自動縮小は複数行では機能しないと思います。私はこのリンクの提案を使用してしまいました複数行のあるUILabelで自動縮小

解決策は、指定された幅でテキストの高さを計算し、テキストが大きい場合は、フォントサイズを縮小し、高さが必要なサイズ以下になるまで同じように実行します。

なぜこれを実装するのが難しいのか分かりません。私が何かを欠けている場合は、誰でも私を修正することができます:)


ここでの他の回答と同様に、欠落している重要な点は、ワードラップを「クリップ」に設定する必要があることでした。直感に反しますが、UILabelを希望の方法で自動縮小するには、これが必要です。これは複数行のUILabelで動作します。
Duncan Babbage

4

これは、Xcode 8.2.1(8C1002)を実行しているSwift 3用です。

私が見つけた最良の解決策は、ストーリーボードまたはIBの固定幅をラベルに設定することです。マージンへの制約を使用して制約を設定します。viewDidLoadに次のコード行を追加します。

override func viewDidLoad() {
            super.viewDidLoad()

            label.numberOfLines = 1
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.5
        }

制約をマージンにラベル付けする

マージンへの固定幅ラベル制約

属性インスペクター

これは魅力のように機能し、新しい行にオーバーフローせず、奇妙な問題なしにテキストをラベルの幅に合わせて縮小し、Swift 3で機能します。


4

それは組み込みUIKit機能や関連フレームワークの一部になっているように思えるので、すばらしい質問です。質問の視覚的な例を次に示します。

フォントのサイズ変更アニメーション

それを回避する簡単な方法はありませんが、それは間違いなく可能です。これを行う1つの方法は、ビューの境界に適度に合うフォントが見つかるまで、プログラムでさまざまなフォントサイズを試すことです。またはのboundingRect()機能をNSString使用してこれを実行できNSAttributedStringます。例えば:

let string = "This is a test"
let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height:CGFloat.greatestFiniteMagnitude)
let size = string.boundingRect(with: infiniteSize, options: [], attributes: [.font: UIFont.systemFont(ofSize: avgSize)] context: nil).size

完全なブルートフォースアプローチよりも効率的にバイナリ検索を実行できます。本当に堅牢なものを探している場合は、正しいワードラップやiOSフォントキャッシュのパフォーマンスなど、もう少し複雑な考慮事項もあります。

簡単な方法で画面にテキストを表示することだけに関心がある場合は、Swiftの堅牢な実装を開発しました。これは、本番環境アプリでも使用しています。これUIViewは、複数行を含む任意の入力テキストに対して効率的な自動フォントスケーリングを備えたサブクラスです。これを使用するには、次のようにします。

let view = AKTextView()
// Use a simple or fancy NSAttributedString
view.attributedText = .init(string: "Some text here")
// Add to the view hierarchy somewhere

それでおしまい!あなたはここで完全なソースを見つけることができます:https//github.com/FlickType/AccessibilityKit

お役に立てれば!


1
2018年11月:FlickTypeが表示され、AccessibilityKitが非公開になったか削除されました。
Chris Paveglio 2018年

3

iOS 9では、次のことを行う必要がありました。

  1. ラベルの左右からスーパービューに制約を追加します。
  2. IBで改行モードをクリッピングに設定します。
  3. IBで行数を1に設定します。

誰かが行数を0に設定することを推奨しましたが、私にとってはこれによりラベルが複数行になるようになりました...


これは私にとってはトリックでした。静的セルでa UILabelとa UITextFieldを選択し、「オートレイアウトの問題を解決」と「欠落している制約を追加」をクリックしました。すべてが揃っていますが、Autoshrinkはラベルまでの距離を知る必要があり、「不足している制約の追加」では制約が追加されませんでした。
エイドリアン

2

alloc init Labelの後に次のコードを書くことができると思います

UILabel* lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, 280, 50)];
lbl.text = @"vbdsbfdshfisdhfidshufidhsufhdsf dhdsfhdksbf hfsdh fksdfidsf sdfhsd fhdsf sdhfh sdifsdkf ksdhfkds fhdsf dsfkdsfkjdhsfkjdhskfjhsdk fdhsf ";
[lbl setMinimumFontSize:8.0];
[lbl setNumberOfLines:0];
[lbl setFont:[UIFont systemFontOfSize:10.0]];
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.backgroundColor = [UIColor redColor];
[lbl sizeToFit];
[self.view addSubview:lbl];

それは私とうまく働いています


1
おかげで、これはフォントを計算したり、私が理解しているように必要な最小に縮小したりしません。また、最小フォントが通常よりも大きいのはなぜですか?
ルーカス、2012年

2

2年後、この問題はまだ残っています...

iOS 8 / XCode 6.1では、自分のUILabelUITableViewCellオンになっていて、十分なスペースがあるように柔軟な制約で)がテキスト文字列に合うようにサイズ変更されない。

解決策は、以前と同様に、テキストを設定してから呼び出すことsizeToFitでした。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    . . .
    cell.lblCreatedAt.text = [note getCreatedDateAsString];
    [cell.lblCreatedAt sizeToFit];
}

(はぁ。)


1

これを行う方法は次のとおりです。次のmessageLabelが目的の効果を持たせたいラベルであるとします。次に、次の簡単なコード行を試してください。

    //SET THE WIDTH CONSTRAINTS FOR LABEL.
    CGFloat constrainedWidth = 240.0f;//YOU CAN PUT YOUR DESIRED ONE,THE MAXIMUM WIDTH OF YOUR LABEL.
 //CALCULATE THE SPACE FOR THE TEXT SPECIFIED.
    CGSize sizeOfText=[yourText sizeWithFont:yourFont constrainedToSize:CGSizeMake(constrainedWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
    UILabel *messageLabel=[[UILabel alloc] initWithFrame:CGRectMake(20,20,constrainedWidth,sizeOfText.height)];
    messageLabel.text=yourText;
    messageLabel.numberOfLines=0;//JUST TO SUPPORT MULTILINING.

回答に感謝しますが、ラベルの高さを計算する必要はありません。サイズを固定しているため、必要に応じてフォントを小さくする必要があります。
Lukas 2012年

1

numberOfLines > 1 私がやったことがこのような状態になった場合は機能しません-

if(lblRecLocation.text.length > 100)
    lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];

0

パーティーに遅刻しましたが、1行に1ワードずつ追加する必要があったので、この1つの追加でうまくいきました。

label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;

Apple Docsは言う:

通常、ラベルテキストは、fontプロパティで指定したフォントで描画されます。ただし、このプロパティがYESに設定されていて、textプロパティのテキストがラベルの境界の長方形を超えている場合、文字列が収まるか、最小フォントサイズに達するまで、レシーバーはフォントサイズの縮小を開始します。iOS 6以前では、このプロパティは、numberOfLinesプロパティが1に設定されている場合にのみ有効です。

しかし、これは嘘です。嘘をつくよ!これは、すべてのiOSバージョンに当てはまります。具体的には、カスタムレイアウト(例)を介して実行時に動的に調整される制約によってサイズが決定されるUILabel内でUICollectionViewCellを使用する場合に当てはまりますself.menuCollectionViewLayout.itemSize = size

したがって、adjustsFontSizeToFitWidthおよびと組み合わせて使用​​するとminimumScaleFactor、以前の回答で述べたように、プログラムnumberOfLinesでワードカウントに基づいて設定することで自動縮小の問題が解決されました。単語数または文字数に基づいて同様のことを行うと、「十分に近い」ソリューションが生成される場合があります。


0

Swift 4(プログラムによる):

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200.0, height: 200.0))
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0

label.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

view.addSubview(label)

0

Swift 4、Xcode 9.4.1

私のために働いた解決策:私はコレクションビューセル内にラベルを持っていて、ラベルテキストがトリミングされていました。ストーリーボードで以下のように属性を設定します

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.