はじめに
AutoLayoutはきちんと設定したのに、デバッグエリアをみると以下のようなメッセージが書かれていることはありませんか??
2020-02-21 22:56:34.775265+0900 TableView[13144:2779148] [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:0x2807d8460 UILabel:0x104a1ae70'\U8679\U8272'.height == 32 (active)>",
"<NSLayoutConstraint:0x2807d28a0 UIStackView:0x107203e70.height == 500 (active)>",
"<NSLayoutConstraint:0x2807e80f0 UILayoutGuide:0x281de0000'UIViewSafeAreaLayoutGuide'.bottom == UIStackView:0x107203e70.bottom (active)>",
"<NSLayoutConstraint:0x2807e82d0 UIStackView:0x107203e70.top == UILayoutGuide:0x281de0000'UIViewSafeAreaLayoutGuide'.top (active)>",
"<NSLayoutConstraint:0x2807d8780 V:|-(0)-[UIStackView:0x104a0f890] (active, names: '|':UITableViewCellContentView:0x104a1c810 )>",
"<NSLayoutConstraint:0x2807d8820 V:[UIStackView:0x104a0f890]-(0)-| (active, names: '|':UITableViewCellContentView:0x104a1c810 )>",
"<NSLayoutConstraint:0x2807dc7d0 'UISV-canvas-connection' UIStackView:0x104a1d4e0.top == TableView.RainbowColorView:0x107203d00.top (active)>",
"<NSLayoutConstraint:0x2807dc820 'UISV-canvas-connection' V:[TableView.RainbowColorView:0x107203d00]-(0)-| (active, names: '|':UIStackView:0x104a1d4e0 )>",
"<NSLayoutConstraint:0x2807d9310 'UISV-canvas-connection' UIStackView:0x104a0f890.top == UILabel:0x104a1ae70'\U8679\U8272'.top (active)>",
"<NSLayoutConstraint:0x2807dc910 'UISV-canvas-connection' V:[UIStackView:0x104a1d4e0]-(0)-| (active, names: '|':UIStackView:0x104a0f890 )>",
"<NSLayoutConstraint:0x2807d93b0 'UISV-spacing' V:[UILabel:0x104a1ae70'\U8679\U8272']-(0)-[UIButton:0x104a1cbb0'\U3053\U3053\U3092\U30bf\U30c3\U30d7\U3057\U3066\U304f\U3060\U3055\U3044'] (active)>",
"<NSLayoutConstraint:0x2807dc960 'UISV-spacing' V:[UIButton:0x104a1cbb0'\U3053\U3053\U3092\U30bf\U30c3\U30d7\U3057\U3066\U304f\U3060\U3055\U3044']-(0)-[UIStackView:0x104a1d4e0] (active)>",
"<NSLayoutConstraint:0x2807d9770 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x104a1c810.height == 64 (active)>",
"<NSLayoutConstraint:0x2807e8190 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x281de0000'UIViewSafeAreaLayoutGuide']-(0)-| (active, names: '|':TableView.RainbowColorView:0x107203d00 )>",
"<NSLayoutConstraint:0x2807e8050 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x281de0000'UIViewSafeAreaLayoutGuide'] (active, names: '|':TableView.RainbowColorView:0x107203d00 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x2807d28a0 UIStackView:0x107203e70.height == 500 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
もしかしたら、制約が競合している可能性があるかもしれません。今回はその場合の、
- 原因
- 対処法
の2点に絞って説明していきます!
※説明が間違っていたら申し訳ありません、、、
環境
- macOS Catalina(10.15.2)
- xcode(11.3)
- Swift5.1
原因
ボタンタップ前 | ボタンタップ後 |
---|---|
今回の場合、ボタンをタップすると虹色が表示され、その途端に上記のメッセージが表示されました。
※全体はUITableViewで単位ごとにUITableViewCellを利用しています。虹色はUIStackViewとUILabelで管理しており、UIStackViewのheight = 500で設定しています。デフォルトでUIStackViewをisHidden = trueで設定しています。
上記のメッセージを読むと、下の方に
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x283fe4910 UIStackView:0x10f901490.height == 500 (active)>
と書かれています。読んでみると、UIStackViewのheight = 500の制約が原因みたいです。もう少し詳しく説明すると、UIStackViewを非表示から表示にすることでUITableViewCellの高さが再計算され、その高さとUIStackViewのheight = 500を同レベルの優先度で同時に満たそうとしていることが原因みたいです。
対処法
方法は至って単純です。UIStackViewのheight = 500の制約のPriorityを下げるだけで解決します。
これにより、制約の競合が発生した場合にUIStackViewのheight = 500の優先順位が下がります。基本的にはこの辺のこともxcodeが計算してくれますが、不具合の原因にもなりかねないのできちんと対応したいところですね笑