iphone 複数行 iOS: 自動レイアウトのマルチライン UI ラベル




xcode label 複数行 (7)

私は自動レイアウトで非常に基本的なレイアウト動作を達成しようとするのに問題があります。 IBのビューコントローラは次のようになります。

一番上のラベルはタイトルラベルですが、何行になるのか分かりません。 すべての行のテキストを表示するには、タイトルラベルが必要です。 私はまた、他の2つのラベルと小さな画像がタイトルのすぐ下に配置される必要がありますが、それは起こります。 ラベルとスモールイメージの間の垂直スペーシング制約と、タイトルラベルとスーパービューの間のスペーシング制約と、スモールイメージとスーパービュー間のボトムスペーシング制約を設定しました。 白いUIViewには高さの制約がないため、サブビューを含むように垂直に伸びる必要があります。 タイトルラベルの行数を0に設定しました。

文字列に必要な行数に合わせてサイズを変更するタイトルラベルを取得するにはどうすればよいですか? 私は、自動レイアウトを使用しているため、setFrameメソッドを使用できないことを理解しています。 そして私はタイトルレイアウトの下にとどまるために他のビューが必要なので、自動レイアウトを使用する必要があります(制約条件)。

これをどうすればいいのですか?


-setPreferredMaxLayoutWidthを使用し、残りの部分はautolayoutが処理します。

[label setPreferredMaxLayoutWidth:200.0];

UILabelのドキュメントを参照してください。

更新:

ストーリーボードの高さの制約を設定する必要があるだけで、より大きいか等しい。setPreferredMaxLayoutWidthは不要。


この問題の多くのトピックで見つかったさまざまな解決策のどれも、私のケースでは完全に機能しませんでした(動的テーブルビューセルの動的な複数行ラベル)。

私はそれを行う方法を見つけた:

ラベルに制約を設定し、multilineプロパティを0に設定した後、UILabelのサブクラスを作成します。 私は私のAutoLayoutLabelと呼んだ:

@implementation AutoLayoutLabel

- (void)layoutSubviews{
    [self setNeedsUpdateConstraints];
    [super layoutSubviews];
    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
}

@end

これを行う1つの方法...テキストの長さが増えるにつれて、ラベルテキストのフォントサイズを変更(減らす)しようとします

Label.adjustsFontSizeToFitWidth = YES;

私はテキストラップラベルを持つUITableViewCellを持っています。 私は以下のようにテキストラッピングを行いました。

1)UILabelの制約を次のように設定します。

2)Noを設定します。 の行を0に設定します。

3)UITableViewCellにUILabelの高さの制約を追加しました。

@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!

4)UITableViewCellについて:

priorityLabel.sizeToFit()
priorityLabelWidth.constant = priorityLabel.intrinsicContentSize().width+5

私はあなたが次が必要であることがわかります:

  • 上限制約
  • 先頭の制約(例えば左側)は、
  • 後続の制約(例えば右側)
  • コンテンツの抱き合わせの優先順位を水平から低い値に設定します。テキストが短い場合は、指定された領域を満たします。
  • コンテンツの圧縮抵抗を水平から低い値に設定して、より広くなるようにする代わりに折り返します。
  • 行数を0に設定します。
  • 改行モードを単語の折り返しに設定します。

私はちょうどこの正確なシナリオで戦っていましたが、必要に応じてサイズを変更して下に移動する必要があるビューがかなりありました。 それは私にナッツを運転していましたが、私はついにそれを理解しました。

ここにキーがあります:Interface Builderは、ビューを追加したり移動したりするときに余分な制約を加えることを好みます。 私の場合は、基本的にそれをそのポイントに固定して、スーパービューとの間のサイズを指定する特別な制約があるビューを半分ダウンさせました。 それは、それがその制約に反するため、それを上回るものはそれ以上大きくならないことを意味しました。

ラベルを手動でサイズ変更しようとすると、これが当てはまるかどうかを簡単に知ることができます。 IBはそれを成長させますか? そうであれば、下のラベルは期待どおりに移動しますか? リサイズする前にこれらの両方をチェックしておき、制約がどのようにビューを動かすかを確認してください。

ビューが停止している場合は、その下にあるビューに従って、いずれかのビューにスーパービュー制約のためのスペースがないことを確認します。 次に、ラベルの行数オプションが0に設定されていることを確認して、残りの部分を処理します。


出典: http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html : http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

複数行テキストの本質的なコンテンツサイズ

UILabelとNSTextFieldの本質的なコンテンツサイズは、複数行のテキストではあいまいです。 テキストの高さは線の幅に依存しますが、これはまだ制約を解決するときに決定されます。 この問題を解決するために、両方のクラスにはpreferredMaxLayoutWidthという新しいプロパティがあり、これは本来のコンテンツサイズを計算するための最大線幅を指定します。

私たちは通常この値を事前に知っていないので、この権利を得るには2段階のアプローチをとる必要があります。 最初にAuto Layoutに作業をさせた後、結果として得られたレイアウトパスのフレームを使用して、推奨最大幅とトリガレイアウトを再度更新します。

- (void)layoutSubviews
{
    [super layoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [super layoutSubviews];
}

[super layoutSubviews]への最初の呼び出しは、ラベルがフレームセットを取得するために必要ですが、2番目の呼び出しは、変更後のレイアウトを更新するために必要です。 2番目の呼び出しを省略すると、NSInternalInconsistencyExceptionエラーが発生します。これは、制約の更新が必要なレイアウトパスを変更したためですが、レイアウトを再度トリガーしなかったためです。

ラベルサブクラス自体でもこれを行うことができます:

@implementation MyLabel
- (void)layoutSubviews
{
    self.preferredMaxLayoutWidth = self.frame.size.width;
    [super layoutSubviews];
}
@end

この場合、最初に[super layoutSubviews]を呼び出す必要はありません。なぜなら、layoutSubviewsが呼び出されると、ラベル自体にフレームが既に存在するからです。

この調整をビューコントローラレベルから行うために、viewDidLayoutSubviewsにフックします。 この時点で、最初の自動レイアウトパスのフレームはすでに設定されており、それらを使用して優先最大幅を設定することができます。

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [self.view layoutIfNeeded];
}

最後に、ラベルのコンテンツの圧縮抵抗の優先順位よりも高い優先順位を持つラベルに明示的な高さ制約がないことを確認します。 それ以外の場合は、コンテンツの計算された高さよりも優先されます。 ラベルの高さに影響を与える可能性があるすべての制約を確認してください。





autolayout