出典: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];
}
最後に、ラベルのコンテンツ圧縮耐性の優先度よりも高い優先度を持つ、ラベルに明示的な高さ制限がないことを確認してください。それ以外の場合は、コンテンツの計算された高さよりも優先されます。ラベルの高さに影響を与える可能性のあるすべての制約を確認してください。