191

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

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

トップラベルはタイトルラベルですが、何行になるかわかりません。すべてのテキスト行を表示するには、タイトルラベルが必要です。また、他の2つのラベルと小さな画像をタイトルのすぐ下に配置する必要がありますが、高さが高くなります。ラベルと小さな画像の間に垂直方向の間隔の制約を設定し、タイトルラベルとそのスーパービューの間に上部の間隔の制約を設定し、小さな画像とそのスーパービューの間に下部の間隔の制約を設定しました。白いUIViewには高さの制約がないため、サブビューを含めるには垂直方向に伸ばす必要があります。タイトルラベルの行数を0に設定しました。

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

どうすればこれを実現できますか?

4

8 に答える 8

262

で使用-setPreferredMaxLayoutWidthするUILabelと、自動レイアウトで残りを処理できます。

[label setPreferredMaxLayoutWidth:200.0];

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

アップデート:

heightストーリーボードの制約をに設定するだけGreater than or equal toでよく、setPreferredMaxLayoutWidthは必要ありません。

于 2012-10-23T14:02:58.340 に答える
216

ラベルセットの行数を0に拡張し、さらに重要なことに、自動レイアウトセットの高さを>=xに拡張します。残りは自動レイアウトで行います。前の要素に基づいて他の要素を含めて、その時点で正しく配置することもできます。

自動レイアウト

于 2013-08-05T02:09:11.390 に答える
53

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

複数行のテキストの固有のコンテンツサイズ

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

通常、この値は事前にわからないため、これを正しく行うには2段階のアプローチをとる必要があります。最初に自動レイアウトに作業を任せ、次にレイアウトパスで結果のフレームを使用して、優先される最大幅を更新し、レイアウトを再度トリガーします。

- (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];
}

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

于 2015-03-21T07:30:13.050 に答える
18

私はこの正確なシナリオと戦っていましたが、必要に応じてサイズを変更したり下に移動したりする必要のあるビューがかなり多くありました。それは私を狂わせていました、しかし私はついにそれを理解しました。

重要な点は次のとおりです。InterfaceBuilderは、ビューを追加および移動するときに追加の制約をスローするのが好きで、気付かない場合があります。私の場合、ビューの途中に、ビューとそのスーパービューの間のサイズを指定する追加の制約があり、基本的にそのポイントに固定されていました。つまり、その制約に反するため、その上のものはサイズを大きくすることはできません。

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

IBメニュー

ビューが動かなくなった場合は、その下にあるビューをたどり、そのうちの1つにスーパービュー制約の上部スペースがないことを確認してください。次に、ラベルの行数オプションが0に設定されていることを確認し、残りを処理する必要があります。

于 2012-10-18T21:03:07.850 に答える
7

次のものが必要だと思います。

  • 上部の制約
  • 先行制約(例:左側)
  • 末尾の制約(例:右側)
  • コンテンツハグの優先度を水平から低に設定して、テキストが短い場合に指定されたスペースを埋めるようにします。
  • コンテンツの圧縮抵抗を水平から低に設定して、幅を広げようとするのではなく、折り返すようにします。
  • 行数を0に設定します。
  • 改行モードをワードラップに設定します。
于 2017-04-11T01:01:03.690 に答える
0

このテーマに関する多くのトピックで見つかったさまざまなソリューションはどれも、私の場合には完全には機能しませんでした(動的テーブルビューセルのx動的複数行ラベル)。

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

ラベルに制約を設定し、その複数行プロパティを0に設定したら、UILabelのサブクラスを作成します。私はAutoLayoutLabelと呼びました:

@implementation AutoLayoutLabel

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

@end
于 2015-09-02T16:34:10.457 に答える
0

テキストラップラベルを持つUITableViewCellがあります。私は次のようにテキストの折り返しを行いました。

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

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

2)セット番号 0への行の。

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

@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!

4)UITableViewCellの場合:

priorityLabel.sizeToFit()
priorityLabelWidth.constant = priorityLabel.intrinsicContentSize().width+5
于 2016-07-28T06:33:07.880 に答える
-12

これを行う1つの方法...テキストの長さが長くなるにつれて、を使用してラベルテキストのフォントサイズを変更(縮小)してみてください

Label.adjustsFontSizeToFitWidth = YES;
于 2012-10-09T08:35:19.300 に答える