縦と横で別のAutoLayoutをつけようとしたら警告が出まくった話


突然だけど

  • 縦画面の時に中央上下にラインを引いたような配置
  • 横画面の時に中央左右にラインを引いたような配置

な画面をAutoLayoutで作りたい(どうしてとか言わない)

サイズクラスごとに制約をつけていく

縦向きの制約をつける

  1. まずは制約をつけるViewを設置して
  2. まずは縦方向の制約だけつけていく
  3. Constantが適当なので整える
  4. できた
1 2 3 4

横向きの制約をつける

  1. 画面を横にして
  2. 横方向の制約だけつけていく
  3. Constantが適当なので整える
  4. できた
1 2 3 4

いざ実機実行!

縦にしても横にしてもStoryboard上では警告出てない!勝ったな!実機で回転させる!!

[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:0x282ebd270 UIView:0x10160e2d0.top == UILayoutGuide:0x283494700'UIViewSafeAreaLayoutGuide'.top + 340   (active)>",
    "<NSLayoutConstraint:0x282ebd2c0 UILayoutGuide:0x283494700'UIViewSafeAreaLayoutGuide'.bottom == UIView:0x10160e2d0.bottom + 350   (active)>",
    "<NSLayoutConstraint:0x282e8d040 'UIView-Encapsulated-Layout-Height' UIView:0x10160a450.height == 390   (active)>",
    "<NSLayoutConstraint:0x282ebd450 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x283494700'UIViewSafeAreaLayoutGuide']-(21)-|   (active, names: '|':UIView:0x10160a450 )>",
    "<NSLayoutConstraint:0x282ebd4f0 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x283494700'UIViewSafeAreaLayoutGuide']   (active, names: '|':UIView:0x10160a450 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x282ebd2c0 UILayoutGuide:0x283494700'UIViewSafeAreaLayoutGuide'.bottom == UIView:0x10160e2d0.bottom + 350   (active)>

ど う し て

じゃなくて警告文を読む(このサイトに警告をコピペで読みやすくなるかも)

以下の制約を同時に満たせません

  • UIViewのtopSafeAreaのtopから+340
  • SafeAreaのbottomUIViewのbottomから+350
  • UIViewの高さが390
  • UIViewのbottomSafeAreaのbottomから+21
  • SafeAreaのtopViewのtop

340、350…🤔

!!消したはずでは…(縦向きの制約をつけるの2枚目の画像)

Vary for Traitsを使う時の注意点

Size inspectorで確かにConstantは修正しました

before after

が、制約をダブルクリックしてみると…

350残っとるやんけ!

僕は以下の手順で制約をつけました

  1. 制約をつけたいViewを設置
  2. Vary for TraitsでheightがRegularのTraitに対してのみ制約をつけるようにする
  3. とりあえずのConstantで制約をつける
  4. Size inspectorからConstantを編集

どうやら、Vary for Traitsを使用中にSize inspectorからConstantを編集した時は新たにConstantを生成するようです
編集しているんだから新たに生成するのはやめて欲しい気もしますが…

Constantを一つにすることで警告は解消されました

しかし不可解

はじめにつけた適当なConstantが残っていたことはわかりました。しかしこの制約はheightがRegularの時にしかactiveにならないはずで、Regularの時のConstantは350ではなく0になるのでは…

いろいろ試してみましたがどうしてもう一方のConstantが有効な制約になってしまうのか突き止められませんでした

もし「こういうことでは🤔」と教えていただける方いましたらぜひよろしくお願いします🥺