先々週あたり、この2件のAutoLayoutのデバッグテクニック系記事が海外で話題になっていてPocketで積ん読状態になっていたので、掘り出しつつ試してみました。
UIViewAlertForUnsatisfiableConstraints
のシンボリックブレークポイントを設定
このブレークポイントを設定することで、文字通りAutoLayoutの制約矛盾が発生した時にブレークしてくれます。
さらに、Action
も設定するのが肝で、この場合は次の設定をするとブレーク時に見やすいログが自動出力されるようになります。
関連: Objective-C - Xcodeでデバッグ実行中にクラッシュした時に捗るブレークポイント設定 - Qiita
-
Objective-C
:po [[UIWindow keyWindow] _autolayoutTrace]
-
Swift
:expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]
捗りそうなログ( ´・‿・`)
ただ、画面遷移後の瞬間に遷移後の画面で制約矛盾が発生した場合、ログに出るレイアウト情報が前の画面で微妙に役立たなかったという問題もありました(´・ω・`)
あと、元記事には書いてないですが、ブレークした状態で、XcodeのView UI Hierarchy
を実行すると、多分良い感じにその画面状態を表示してくれるはずです。
最近、Xcodeの調子が悪くて、こういう操作するとクラッシュしてしまい、僕はちゃんと見られるのか確認出来てないですが(´・ω・`)
制約に名前を付ける(Xcode 7〜)
WWDCの発表に含まれていたようですがXcode 7ではこんな風に、制約はIdentifier
というプロパティがあり、それを設定することでログに制約名が出るようになるようです。
コードの場合は、こうですね。
constraint.identifier = "$GemeInfoBottom$"
確かに、ログに名前が出てきました。分かりやすい( ´・‿・`)
2015-08-31 09:59:13.223 Player[80154:6146881] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7f8a42dd76c0 V:[UIImageView:0x7f8a4517b0c0(44)]>",
"<NSLayoutConstraint:0x7f8a42d1e110 UITableViewCellContentView:0x7f8a42decfd0.centerY == UIImageView:0x7f8a4517b0c0.centerY>",
"<NSLayoutConstraint:0x7f8a4514a2b0 '$GemeInfoBottom$' V:[UIImageView:0x7f8a4517b0c0]-(>=8)-| (Names: '|':UITableViewCellContentView:0x7f8a42decfd0 )>",
"<NSLayoutConstraint:0x7f8a453047f0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7f8a42decfd0(59.5)]>"
)
全制約に予め付けておくと捗りそうですが、けっこう手間ではありますね(´・ω・`)