Cocoa Autolayout:コンテンツハグとコンテンツ圧縮耐性の優先順位


643

Cocoa Autolayoutに関するAppleのドキュメントで、コンテンツハグと圧縮耐性の違いについて明確な答えが見つかりません。

誰かがその使用法と違いを説明できますか?


49
生命の大きな神秘の1つは、彼らがそれを単に「拡張抵抗」と呼ばなかった理由です。この2つの特性は、「拡張抵抗」と「圧縮抵抗」にすぎません。「抱きしめる」用語は正気ではありません。
Fattie 2017

3
場合あなたはあまりにも多くの部屋を持っているcontent-hugging:ホワイトスペースを持つと戦うでしょう。それはあなたの周りにビューを強制するだけです。しかしスペースがあまりなく、代わりに場所が非常に少ない場合content-compressions-resistance、すべてのコンテンツを表示できないことからビューに対抗します。たとえば、ラベルが切り捨てられます。
ハニー、

回答:


1319

概念の簡単な要約:

  • ハグ=>コンテンツは成長したくない
  • 圧縮抵抗=>コンテンツは縮小したくない

例:

次のようなボタンがあるとします。

[       Click Me      ]

優先度500の大きなスーパービューにエッジを固定しました。

次に、抱き優先度> 500の場合、次のようになります。

[Click Me]

ハグの優先度が500未満の場合、次のようになります。

[       Click Me      ]

スーパービューが縮小した場合、圧縮抵抗の優先度が500を超えると、次のようになります。

[Click Me]

それ以外の場合、圧縮耐性の優先順位が500未満の場合、次のようになります。

[Cli..]

このように機能しない場合は、他のいくつかの制約が発生していることが原因で、正常な動作が台無しになっている可能性があります。

たとえば、優先度1000でスーパービューに固定することができます。または、幅優先度を持つこともできます。もしそうなら、これは役に立ちます:

エディター>コンテンツに合わせたサイズ


37
優先度== 500を抱いている場合はどうなりますか?
bradley.ayers 2013

1
私はそれが通常の丸め動作のように> 500として扱われると仮定します(しかし、それは通常は良い考えではありません)。まだテストしていません。
Joshua Nozzi 2013

ほとんどの場合、実行時に「制約を同時に満たすことができません」という警告が表示されます
Max Desiatov

8
@ bradley.ayers MaxDesyatovのコメントには、必要な優先度(1000)で競合する制約がある場合にのみ発生します。2つの優先度の低い制約が競合する場合、解決策はあいまいであるため、自動レイアウトエンジンは有効な解決策を1つだけ選択し、それが表示されます(警告なし)。レイアウトがどのように表示されるかを選択するのは自動レイアウトエンジンの内部実装次第であり、理論的にはこれはiOSのバージョンによって変わる可能性があるため、明らかにこれは適切ではありません。
スマイリーボー2014年

コンテンツハグの優先度のデフォルトは250で、コンテンツ圧縮耐性のデフォルトは750です。なぜ500を使用するのでしょうか。
ZYiOS

292

Autolayoutに関するこのビデオチュートリアルをてください。彼らはそれを注意深く説明しています

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


1
@fatuhokuもう一度確認できます。このビデオは無料です
onmyway133 '06 / 06/26

31
ハグとレジスタンスの議論は、ビデオの13:15頃に始まります。
カールスミス

1
@ onmyway133これは完璧なビデオですが、残念ながらレイがどのように使用するか例はありません。
Alexander 14

@MatrosovAlexander非常に実用的な例は、Autolayoutを使用
1468

1
彼は18:05に圧縮抵抗を使用する方法を示しています
ブレントファウスト

187

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

ソース:@mokagio

固有のコンテンツサイズ -かなり自明ですが、可変コンテンツのビューはコンテンツの大きさを認識し、このプロパティを通じてコン​​テンツのサイズを説明します。固有のコンテンツサイズを持つビューのいくつかの明らかな例は、UIImageViews、UILabels、UIButtonsです。

コンテンツハグの優先度 -この優先度が高いほど、ビューは本来のコンテンツサイズよりも大きくなることに抵抗します。

コンテンツの圧縮耐性の優先順位 -この優先順位が高いほど、ビューは固有のコンテンツサイズよりも小さく縮小に抵抗します。

詳細については、ここを確認してください:自動レイアウトマジック:コンテンツサイズの優先順位


イラストはいいですが、控えめに言っても誤解を招きやすいです。トップの男は「私は(私を成長させ)させない」と言うべきです 子ビューは、コンテンツハグ動作によって成長したくないことを独自に定義します。それが成長するのを止める外因性の力(図解された手のような)はありません。それは大きな違いです。
マヌエル

6
私はイラストが好きだからという理由だけで投票します。
James Bucanek

3
これが私がスタックオーバーフローを愛している理由です... Snowcrashの説明とmokagioによるこのイラスト=これらのプロパティの最も良い説明(アップル独自のドキュメントを含む)。
Kal

40

「Click Me」というテキストのボタンがあるとします。そのボタンはどのくらいの幅にする必要がありますか?

まず、ボタンをテキストよりも小さくしたくはありません。そうしないと、テキストが切り取られます。これは、水平圧縮耐性の優先順位です。

次に、ボタンを必要以上に大きくしたくない。このような[Click Me]ボタンは明らかに大きすぎます。ボタンに余計な余白を与えずにボタンのコンテンツを「ハグ」したいとします。これは水平コンテンツのハグの優先順位です。ボタンの場合、水平方向の圧縮抵抗の優先度ほど強力ではありません。


19

の場合view.intrinsicContentSize.width != NSViewNoIntrinsicMetric、自動レイアウトはタイプの特別な制約を作成しますNSContentSizeLayoutConstraint。この制約は、2つの通常の制約のように機能します。

  • view.width <= view.intrinsicContentSize.width水平ハグの優先順位で必要な制約、および
  • view.width >= view.intrinsicContentSize.width水平圧縮抵抗の優先度で必要な制約。

Swiftでは、iOS 9の新しいレイアウトアンカーを使用して、次のような同等の制約を設定できます。

let horizontalHugging = view.widthAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalHugging.priority = view.contentHuggingPriority(for: .horizontal)

let horizontalCompression = view.widthAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalCompression.priority = view.contentCompressionResistancePriority(for: .horizontal)

同様に、の場合view.intrinsicContentSize.height != NSViewNoIntrinsicMetric、自動レイアウトはNSContentSizeLayoutConstraintビューの高さに対する2つの制約のように機能するを作成します。コードでは、次のようになります。

let verticalHugging = view.heightAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalHugging.priority = view.contentHuggingPriority(for: .vertical)

let verticalCompression = view.heightAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalCompression.priority = view.contentCompressionResistancePriority(for: .vertical)

これらの特別なNSContentSizeLayoutConstraintインスタンス(存在する場合)はview.constraints、レイアウトの実行後に印刷することで確認できます。例:

label.constraints.forEach { print($0) }

// Output:
<NSContentSizeLayoutConstraint:0x7fd82982af90 H:[UILabel:0x7fd82980e5e0'Hello'(39)] Hug:250 CompressionResistance:750>
<NSContentSizeLayoutConstraint:0x7fd82982b4f0 V:[UILabel:0x7fd82980e5e0'Hello'(21)] Hug:250 CompressionResistance:750>

1
そうでない場合:let verticalCompression = view.heightAnchor.constraint(greatThanOrEqualToConstant:view.intrinsicContentSize.height)
mc_plectrum

1
はい、コピー/貼り付けエラーが発生しました。修正しました。お知らせいただきありがとうございます。
rob mayoff 2017年

15

コンテンツハグとコンテンツ圧縮耐性の優先度は、入ってくるコンテンツに応じて本質的にサイズを計算できる要素に対して機能します。

Apple docsから:

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


画像のplus1(Y)
Noor Ali Butt

よくわかりません。スクロールが有効になっていないtextViewの場合。それは、ユーザーごとに固有のサイズを入力することで変化することを意味しますか?
蜂蜜

@Honey正しい制約を設定し、スクロールを無効にすると、テキストビューで固有の高さを認識できるはずです。
dev gr 2017

それは私の質問に答えませんでした。つまり、textViewの現在のサイズよりも多く入力すると、textViewが自動的に拡張されて本来のサイズが変更されますか?
ハニー

自分で試してみてください。textviewの幅を固定し、スクロールを無効にして、目的の動作を確認します。詳細については、stackoverflow.com / a / 21287306/1526629を参照してください。
dev gr 2017

11

これContent hugging priorityは、ビューの周りに配置されるラバーバンドのようなものです。優先度の値が高いほど、ラバーバンドが強くなり、コンテンツのサイズに強く抱きしめられます。優先度の値は、ラバーバンドの「強さ」のように想像できます。

そして、ビューがContent Compression Resistanceどれだけ小さく「抵抗」することになり ます。抵抗優先度の値が高いビューは、圧縮に抵抗するビューです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.