topLayoutGuideが曖昧(AMBIGUOUS)でハマるケース
概要
謎のレイアウト崩れ。autolayoutでハマって半日以上浪費したので備忘録。
多分、autolayoutの最適化周りのバグ。view構造をバラして展開してくれるのはいいんだけど、それ故にあっちのアレが明後日の場所でエラーりましたよ、と。
結論としては、
- navigationViewControllerのせいでまだ曖昧なとこがあるうちに
- viewControllerのviewに貼り付けたCustomViewの中で使ってたautolayoutを解決しようとして
- view構造を展開してから解決しようとして
- 曖昧なままのUILayoutGuide(topLayoutGuide)との関係性が生まれ、計算しようとして、エラー。
- エラーったから、適当に解決するね → レイアウト崩れ
ということらしく。
多分タイミングというか依存性解決に失敗してる感あるなあと、試しに
適当なタイミング(viewWillAppear:)でviewControllerに
self.view.layoutIfNeeded()
させておいたら直るという。
ほんと やめて、っていう。
状況
いつの間にか、レイアウト崩れが発生している!?
なんかよくわからんけど、autolayoutがエラーって、勝手にConstraintぶっ壊してくれる、、、
なにこれ。
2018-08-07 16:42:05.366607+0900 HogeFuga Develop[65798:3081762] [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.
(
"<_UILayoutSupportConstraint:0x600000286180 _UILayoutGuide:0x7f8602071450.height == 0 (active)>",
"<_UILayoutSupportConstraint:0x6000002858c0 V:|-(0)-[_UILayoutGuide:0x7f8602071450] (active, names: '|':UIView:0x7f8602069610 )>",
"<NSLayoutConstraint:0x600000287df0 UIStackView:0x7f8602069800.height == 38 (active)>",
"<NSLayoutConstraint:0x6000002871c0 V:|-(0)-[HogeFuga.THCalendarWeekdaysView:0x7f8602062bb0] (active, names: '|':HogeFuga.THCalendarView:0x7f8602062670 )>",
"<NSLayoutConstraint:0x600000287170 HogeFuga.THCalendarWeekdaysView:0x7f8602062bb0.height == 22 (active)>",
"<NSLayoutConstraint:0x600000287120 V:[HogeFuga.THCalendarWeekdaysView:0x7f8602062bb0]-(0)-[UICollectionView:0x7f86038c4800] (active)>",
"<NSLayoutConstraint:0x6000002882a0 V:[UIStackView:0x7f8602069800]-(0)-[HogeFuga.THCalendarView:0x7f8602062670] (active)>",
"<NSLayoutConstraint:0x600000288340 V:[_UILayoutGuide:0x7f8602071450]-(0)-[UIStackView:0x7f8602069800] (active)>",
"<NSAutoresizingMaskLayoutConstraint:0x600000090c70 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' UIView:0x7f8602069610.minY == 0 (active, names: '|':UIViewControllerWrapperView:0x7f8602071d90 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600000287120 V:[HogeFuga.THCalendarWeekdaysView:0x7f8602062bb0]-(0)-[UICollectionView:0x7f86038c4800] (active)>
読むと、上から下に流れる感じの変哲のないレイアウトで、エラーる要因がない。
wtfautolayout.com とかで眺めても、どう見ても正しい。
おかしい。
まさか一番上の_UILayoutGuide:0x7f8602071450
が悪いとは(ry
調べる
まずは
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
と言われるままに
UIViewAlertForUnsatisfiableConstraints
とかいうシンボルにブレークポイントを設定。
すると、変なとこで引っかかる。
•UINavigationBar:0x7fd502e0fc90
| _UIBarBackground:0x7fd502e0c1e0
| | UIImageView:0x7fd502e11f60
| | UIVisualEffectView:0x7fd502e12190
| | | _UIVisualEffectBackdropView:0x7fd502e5fa90
| | | _UIVisualEffectSubview:0x7fd502e5eec0
| _UINavigationBarLargeTitleView:0x7fd502e14020'2017年8月'
| | UILabel:0x7fd502e15390
| •_UINavigationBarContentView:0x7fd502e123f0'2017年8月'
| | *<UILayoutGuide: 0x6080001a6040 - "BackButtonGuide(0x7fd502e129e0)", layoutFrame = {{0, 0}, {24, 44}}, owningView = <_UINavigationBarContentView: 0x7fd502e123f0; frame = (0 0; 375 44); layer = <CALayer: 0x60800002bbc0>>>
| | *<UILayoutGuide: 0x6080001a6120 - "LeadingBarGuide(0x7fd502e129e0)", layoutFrame = {{24, 0}, {0, 44}}, owningView = <_UINavigationBarContentView: 0x7fd502e123f0; frame = (0 0; 375 44); layer = <CALayer: 0x60800002bbc0>>>- AMBIGUOUS LAYOUT for UILayoutGuide:0x6080001a6120'LeadingBarGuide(0x7fd502e129e0)'.minX{id: 610}, UILayoutGuide:0x6080001a6120'LeadingBarGuide(0x7fd502e129e0)'.Width{id: 613}
| | *<UILayoutGuide: 0x6080001a6200 - "TitleView(0x7fd502e129e0)", layoutFrame = {{24, 0}, {343, 44}}, owningView = <_UINavigationBarContentView: 0x7fd502e123f0; frame = (0 0; 375 44); layer = <CALayer: 0x60800002bbc0>>>- AMBIGUOUS LAYOUT for UILayoutGuide:0x6080001a6200'TitleView(0x7fd502e129e0)'.minX{id: 612}, UILayoutGuide:0x6080001a6200'TitleView(0x7fd502e129e0)'.Width{id: 616}
| | *<UILayoutGuide: 0x6080001a62e0 - "TrailingBarGuide(0x7fd502e129e0)", layoutFrame = {{367, 0}, {0, 44}}, owningView = <_UINavigationBarContentView: 0x7fd502e123f0; frame = (0 0; 375 44); layer = <CALayer: 0x60800002bbc0>>>- AMBIGUOUS LAYOUT for UILayoutGuide:0x6080001a62e0'TrailingBarGuide(0x7fd502e129e0)'.minX{id: 615}, UILayoutGuide:0x6080001a62e0'TrailingBarGuide(0x7fd502e129e0)'.Width{id: 619}
| | *<UILayoutGuide: 0x6080001a63c0 - "UIViewLayoutMarginsGuide", layoutFrame = {{16, 0}, {343, 44}}, owningView = <_UINavigationBarContentView: 0x7fd502e123f0; frame = (0 0; 375 44); layer = <CALayer: 0x60800002bbc0>>>
| | *UILabel:0x7fd502f42300'2017年8月'
| +_UINavigationBarModernPromptView:0x7fd502e19fb0
| | *UILabel:0x7fd502e1a4e0
AMBIGUOUS LAYOUT for UILayoutGuide
と出てるのが、autolayout的に曖昧なトコロ。
これ、どういうこと?
関係あるの?とちゃんと見比べていれば、あるいはすぐ問題解決できたかもしれません。
どゆこと?と他に理由を探したのが間違い。
わからないので、一番怪しそうなNSAutoresizingMaskLayoutConstraint
を殺すべく、translatesAutoresizingMaskIntoConstraints
をfalseにしてみてくが
ViewControllerのviewにresizingMask付けなかったらダメじゃん、と、つまり違うらしい。
続いてAutolayoutGuide::デバッグに役立つヒントとかを眺めつつ
デバッガコンソールでconstraintsAffectingLayoutForAxis
とかを叩くも、返ってくるのは期待してる通りの正常っぽい結果。
もはや誰が敵かわからなくなり、collectionViewだからいけないのではないか、とか
いやあるいはstoryboardのオプションが、とか色々試し出す。
混乱と疑心暗鬼。
解決
以前は動いていた、今は動いてない。
ならば、前の状況に近付けて、切り分けを、、、は面倒なので
代わりに、ばっさばっさとコメントアウトを行い、ちゃんと動く状態を作り出す。
Storyboard上で配置されてる要素を ばっさばっさと捨てながら、動くところまで持っていく。
- 縦方向のレイアウトの問題
なのは自明だったので、それに基づいて、色々試して傾向をみる。
結果的に、上側のConstraintを切るとちゃんと動いたので、ええーっと、となり
それまで試したCompressionResistancePriorityなり
intrinsicContentSizeを設定してみたりと努力は無駄でした。ちゃんちゃん。
topLayoutGuideとかOS(ランタイム)側がよしなにしてくれるトコの認識だから
まさかそんなのが悪いとか思い付かなかったよ・・・
再現性
もう精魂果てたので、誰か暇なら再現性確認してバグレポート投げて、、、
Author And Source
この問題について(topLayoutGuideが曖昧(AMBIGUOUS)でハマるケース), 我々は、より多くの情報をここで見つけました https://qiita.com/touta/items/e72940f8fe8e9967e9f4著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .