49686


[VerticalなStackViewの中に置いたViewの左右に10ポイントの空白を設けたいが、Conflicting
Constraintsする](https://ja.stackoverflow.com/questions/49649/vertical%E3%81%AAstackview%E3%81%AE%E4%B8%AD%E3%81%AB%E7%BD%AE%E3%81%84%E3%81%9Fview%E3%81%AE%E5%B7%A6%E5%8F%B3%E3%81%AB10%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E7%A9%BA%E7%99%BD%E3%82%92%E8%A8%AD%E3%81%91%E3%81%9F%E3%81%84%E3%81%8C-conflicting-
constraints%E3%81%99%E3%82%8B)

↑によって左右に空白を設けることができました。

`StackView`を扱うには中に`View`を置いてさらにその中に部品を配置していけばよいことがわかりました。

そこで、添付画像のようにボタンを置きました。  
ボタンの高さは`Intrinsic Content Size`によって自動で決定されると認識しています。

この`Intrinsic Content Size`の高さと`View`の高さを同じにしたいです。

やってみたところ、同じになりましたが意図と違いました。  
Viewの高さが決定された後で、そのViewの高さがボタンの高さにに設定されているように感じます。

`内側のボタン`の`サイズ`に基づいて`View`のサイズを決定させてやるにはどうすればよいのでしょうか？

* * *

[![画像の説明をここに入力](https://i.stack.imgur.com/QYXIe.png)](https://i.stack.imgur.com/QYXIe.png)


CC BY-SA 4.0
2018-10-26T01:47:08.803
49671
2018-10-26T11:00:07.123
9008
question
swift ios autolayout
VerticalなStackviewの中に置いたViewの高さを内側のボタンサイズによって決定させたい


  1. 質問画面左側の`Constraint`のうち、期待する`View`の高さの`Constraint`を他のUI部品と同じように`Files Owner`(多分`ViewController`)のアウトレットにします（ここでは便宜的に`constraintButtonViewHeight`とします）

  2. `View`にボタンを配置したときか、最初からボタンが配置されているのであれば、`viewDidLoad()`で、`constraintButtonViewHeight.constant = button.frame.size.height`とします

  3. `button`を`addSubView()`した`view`に対して、`.layoutIfNeeded()`を呼び出します


CC BY-SA 4.0
2018-10-26T04:49:03.967
49674
2018-10-26T08:38:43.783
2018-10-26T08:38:43.783
14745
14745
49671
answer


まずUIKitのコンポーネントにはUILabelやUIButton、UIImageViewなどのようにIntrinsic Content
Sizeを持つものとUIViewなどIntrinsic Content Sizeを持たないものがあります。  
（前者についてもテキストが複数行に渡る場合などは幅を与える必要があるなど細かい違いはいろいろあります）

UIButtonは自身のコンテンツ（テキストや画像）に応じてIntrinsic Content
Sizeが決まるので原則としてはそれを利用します。そうすると長いテキストであっても自然にサイズと位置が調整されるのでAuto
Layoutのメリットが享受できます。  
（フォントサイズを小さく設定している場合や、テキストが短いことがわかっている場合（「OK」や「了解」など）はボタンについては小さくなりすぎて押しにくくなるため、あえて幅や高さの制約を与えることはあります。その場合でも最低44pt以上の高さを確保するなどの指定が好ましく、Equal制約ではなくGreaterThan制約を付ける方がいいです。）

まずボタンですが、ボタンはコンテンツに応じてIntrinsic Content
Sizeを持つので、タテヨコそれぞれ１つ以上の制約があれば全体の制約を満たすことができます。

下のスクリーンショットはボタンに水平・垂直方向についてセンタリングの制約をつけたものです。それだけで制約が満たされていることがわかります。

[![画像の説明をここに入力](https://i.stack.imgur.com/1c4A1.png)](https://i.stack.imgur.com/1c4A1.png)

一方UIViewはIntrinsic Content
Sizeを持たないので、タテヨコそれぞれ２つ以上の制約が必要です。一般的には高さと幅を何らかの方法で与える必要があります。

下のスクリーンショットはUIViewに水平・垂直方向についてセンタリングの制約をつけたものです。これだけでは制約が足りないのでエラーが出ています。

[![画像の説明をここに入力](https://i.stack.imgur.com/KZk8P.png)](https://i.stack.imgur.com/KZk8P.png)

制約を満たすためには幅と高さを何らかの方法で決定する必要があります。  
制約によって指定する以外にサブビューの大きさによって外側のビューの高さが決まるようにするには、制約が上下・左右の両端に切れ目なく繋がるようにします。

下のスクリーンショットは、上記のビューのサブビューとしてボタンを追加し、ボタンとビューの制約として上下・左右に10ptのマージンを設定したものです。

ビューの制約は先ほどと同様にタテヨコのセンタリングだけですが、ビューのサイズがボタンの幅と高さ（＋制約のマージン）によって決定できるのでエラーが消えていることがわかります。ビューの大きさもAuto
Layoutによって自動的に最適な大きさになりました。

これが基本です。

[![画像の説明をここに入力](https://i.stack.imgur.com/G4Hsl.png)](https://i.stack.imgur.com/G4Hsl.png)

今回の例ではそのほか複数の要因によって最終的に制約がどう解決されるのかが変わるので、難しいのですがこの基本を応用することになります。

まず内部の入れ子にしたビューにボタンを置いて、上下・左右方向に切れ目なく繋がるように制約を付けます。わかりやすいように10ptにしていますが、ぴったり同じ大きさにしたい場合は0ptにすればいいです。

ここで一度実行してみてください。今回の場合、高さを決まっているビューが片方のビューだけなので、余った空間をUIStackViewがどのように解決するかはStoryboard上のシミュレーションと異なる場合があります。

他に条件がなければ下記のような見た目の挙動が得られるはずです。  
UIStackViewの設定はFill/Fillを想定しています。

[![画像の説明をここに入力](https://i.stack.imgur.com/gFzmS.png)](https://i.stack.imgur.com/gFzmS.png)

もし下記のようにUIStackViewの高さの制約が優先され、ボタンが上下・左右の制約を満たすように拡大された場合、解決方法はいくつかありますが、１つはボタンが拡大しないように優先度を設定します。

[![画像の説明をここに入力](https://i.stack.imgur.com/KzCFH.png)](https://i.stack.imgur.com/KzCFH.png)

ボタンを選択してContent Hugging Priorityを1000(Required)に設定します。  
Content Hugging Priorityはコンポーネントの「大きくなりにくさ」を設定します。

[![画像の説明をここに入力](https://i.stack.imgur.com/nC7Qu.png)](https://i.stack.imgur.com/nC7Qu.png)

これによりボタンのサイズが大きくならない優先度が必須（=1000）なので、ボタンのサイズを維持したまま上下・左右の制約を満たそうとするので、ボタンの大きさは本来のままで、余った領域が拡大する形でレイアウトが解決されます。


CC BY-SA 4.0
2018-10-26T11:00:07.123
49686
2018-10-26T11:00:07.123
5519
49671
answer