Edited at

UIStackView 内の view を非表示にしたら、AutoLayout の警告が出る

More than 1 year has passed since last update.


みんな使ってるの?

UIStackView というと、Android でいう LinearLayout みたいなものなのですが、個人的に使いにくくて仕方ないです。

世の中の iOS アプリ開発してる方々は、業務でも使ってるんでしょうか?

なかなか狙ったレイアウトにできなくて、時間ばかり掛かる気がするんですが、自分が使い方ちゃんと理解してないからなのだろうか・・・。(正直、swift も業務で使われてるのか半信半疑ですが・・・)

文句ばかり書きましたが、UIStackView 内の view を非表示にすることで、Android の View.GONE みたいに、その view の分レイアウトを詰めて表示できたりするので、そういう点では便利なのかもしれません。


文句言ってないで使ってみる

慣れるために色々やってみているのですが、以下のようなパターンで警告が大量に出てしまったので、その解決策です。

スクリーンショット1

大したレイアウトではないのですが、UIStackView の中に、UIImageView と UIStackView が入っています。

そして、中にある UIStackView の中に、UILabel が3つ。

ありがちといえばありがちなレイアウトだと思います。

スクリーンショット2 スクリーンショット3

UIImageView には、幅とアスペクト比の制約をつけています。

この状態で実行すると、特に警告もなく正常に表示されます。


view.hidden = YES で警告が

次に、コードで以下のようにしてみます。

- (void)viewDidLoad {

[super viewDidLoad];
self.imageView.hidden = YES;
}

はい、起動時に左側にある UIImageView を非表示に設定してみます。

画像が非表示になって、ラベルたちが左側によって表示される、はず。

ですが、これをやると一応正しく表示されますが、ログに以下の警告が出てきます。

2017-04-14 22:41:49.655702+0900 StackViewTest[1485:103003] [LayoutConstraints] Unable to simultaneously satisfy constraints.

Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x608000098f10 UIImageView:0x7fa4b1608aa0.width == 101 (active)>",
"<NSLayoutConstraint:0x61000009bc60 'UISV-hiding' UIImageView:0x7fa4b1608aa0.width == 0 (active)>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x608000098f10 UIImageView:0x7fa4b1608aa0.width == 101 (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

制約つけるの間違えたときに出てくる、あの警告ですね。

hidden を YES にしただけなのに、何が問題なんだ。


解決

imageViewの制約を、以下のようにしたところ、一応警告は出なくなりました。

スクリーンショット4

幅の制約の Priority を 1000 → 999 にしました。

理屈は正直良くわかってませんw

こういうところが、UIStackView を使いにくいと感じるのかもしれません。

ちなみになのですが、この警告が起きるのは、UIStackView 内に2つ以上 view があって、左側(Axis が Vertical の場合は上側)の view に幅(Axis が Verticalの場合は高さ)の制約がついてるときのみのようです。