web-dev-qa-db-ja.com

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

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

私のxibで、UILabelsautoshrinkがチェックされ、行数が0に設定され、また私の文字列に改行記号(\ n)があります。そして、私はlinebreakmode to wordwrapを選択しました。たぶん誰かが私と同じ状況にあり、私を助けることができますか?本当にありがたいです。

前もって感謝します!

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

106
Lukas

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

タイトル文字列をラベルの境界矩形に合わせるためにフォントサイズを縮小するかどうかを示すブール値。(このプロパティは、 numberOfLinesプロパティは1に設定されます。

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

文字の間隔を調整してラベルの境界矩形内の文字列に合わせるかどうかを示すブール値。(非推奨)

@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth

ソース

150
lester

これは、iOS 9.2、Xcode 7.2でUILabel Autoshrink作業(特に6s Plus Storyboardから4sデバイスのラベルフォントの高さ)を取得する方法です...

enter image description here

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

minimumFontSizeはiOS 6で廃止されました。

したがって、minimumScaleFactorの代わりにminmimumFontSizeを使用します。

lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;
68
user2681543

また、私の解決策はブール値のlabel.adjustsFontSizeToFitWidth = YESです。しかし。インターフェイスビルダーで、Word Wrappingスイッチを「CLIP」に切り替える必要があります。次に、ラベルを自動圧縮します。これはとても重要です。

19
loki-e

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

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

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

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";

これがお役に立てば幸いです:-)返信を待っています

5
Birju

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

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

override func viewDidLoad() {
            super.viewDidLoad()

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

label constraints to margin

fixed width label constraints to margin

attributes inspector

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

4

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

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

なぜこれを実装するのが難しいのか理解できません。私が何かを逃しているなら、誰でも私を修正することを歓迎します:)

3
Lukas

次のコードを書くことができると思います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];

それは私とうまく働いていますそれを使用してください

2
iDhaval

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

IOS 8/XCode 6.1では、UILabelUITableViewCellで作成され、AutoLayoutがオンになっていて、柔軟な制約があるため十分なスペースがありません)が収まるようにサイズが変更されないことが時々ありましたテキスト文字列。

解決策は、以前と同様に、テキストを設定し、then call sizeToFitにすることでした。

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

(はぁ。)

2
Mike Gledhill

IOS 9では、次のことが必要でした。

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

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

2
Nick Yap

それは、組み込みのUIKit機能または関連するフレームワークの一部になると思われるため、これは素晴らしい質問です。質問の視覚的な例は次のとおりです。

Font resizing animation

簡単な方法はありませんが、それは間違いなく可能です。これを行う1つの方法は、ビューの境界にかなり近いサイズが見つかるまで、さまざまなフォントサイズをプログラムで試すことです。これは、NSStringまたはNSAttributedStringboundingRect()関数で実現できます。例えば:

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

完全なブルートフォースアプローチよりも効率的にバイナリ検索を実行できます。本当に堅牢なものを探している場合は、正しいWordの折り返しや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

numberOfLines > 1の場合は機能しません

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

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)

方法は次のとおりです。次の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.
1
Anand

パーティーに遅れて来ましたが、行ごとに1つのWordを持つという追加の要件があったため、この1つの追加が私にとってのトリックを行いました。

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

Apple Docs say:

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

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

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

0
Justin Whitney

Swift 4、Xcode 9.4.1

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

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
0
Naishta