Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
63
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@akatsuki174

Auto Layoutのワーニング解読には「WTF?」が便利

iOSエンジニアなら、Auto Layoutの制約がうまく設定できず、コンソールにワーニングがぞろぞろと出てくる事態に遭遇したことがあるのではないでしょうか。ずらずら並んだワーニングを読みたくない--そんな気持ちを少しでも軽減できるツール、WTF?(Why The Failure, Auto Layout?)を紹介しようと思います。

どんなツール?

Auto Layoutでワーニングログが出てきたときに、制約のコンフリクトを視覚化してくれるツールです。コードはGitHubで公開されています。

ここからは具体例を用いて説明します。

使用例

作りたいレイアウト

こんなレイアウトを作りたいと思って、コードでAuto Layouを使いつつ書いたとします。self.viewの上にグレーのview、そのまた上にUILabelを置いたレイアウトです。UILabelは左右中央、横幅はself.viewの0.85になるように制約をかけています。
スクリーンショット 2018-08-26 17.54.37.png

ワーニングログ

が、なぜかうまく描画されず、ワーニングログが出ています。

[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. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x60800009c2a0 h=--& v=--& UILabel:0x7fc150013250'\U30b7\U30e3\U30a4\U30cb\U30f3\U30b0\n\U30de\U30f3\U30c7\U3047\U3047\U3047\U3047'.width == 0   (active)>",
    "<NSLayoutConstraint:0x60c000280230 UILabel:0x7fc150013250'\U30b7\U30e3\U30a4\U30cb\U30f3\U30b0\n\U30de\U30f3\U30c7\U3047\U3047\U3047\U3047'.width == 0.85*UIView:0x7fc14de15fd0.width   (active)>",
    "<NSLayoutConstraint:0x60c000280d70 'UIView-Encapsulated-Layout-Width' UIView:0x7fc14de15fd0.width == 320   (active)>"
)
Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x604000282ad0 'UIView-Encapsulated-Layout-Width' superView.width == 320   (active, names: superView:0x7f9ed14073d0 )>

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.

WTF?に入力してみる

ここで今回のツールを使ってみたいと思います。トップページはこのようになっています。
スクリーンショット 2018-08-26 18.04.40.png
ここの記述に従い、先程のワーニングログの中の、()で囲まれた部分をペーストし、「Go!」ボタンをクリックすると…
スクリーンショット 2018-08-26 18.09.12.png
このように視覚的に表示されます。でも、まだわかりにくいかもしれません。ということで今度はviewにidentifierを付けてもっと見やすくしてみましょう。次の3行を足します。

self.view.accessibilityIdentifier = "superView"
coverView.accessibilityIdentifier = "coverView"
messageLabel.accessibilityIdentifier = "messageLabel"

もしStoryboard上でレイアウトを描いている場合はXcodeの右ペインからAccessibilityのIdentifierから設定をしてください。
スクリーンショット 2018-08-26 18.14.43.png
この状態でもう一度WTF?にワーニングを入力すると…
スクリーンショット 2018-08-26 18.16.50.png
非常に見やすくなりました。

解読してみる

一番目の制約からしてダメそうです。messageLabelのwidthが0になっています。
スクリーンショット 2018-08-26 18.16.50.png
一番後ろに注釈の*印が付いているので、注釈を見てみます。
スクリーンショット 2018-08-26 18.16.50 2.png
「もしこの制約が意図通りではなかったらtranslatesAutoresizingMaskIntoConstraintsをfalseにしてみてね」と言っています。自分でコード上で生成したviewをAuto Layoutに適用させるときには、こいつをfalseにする必要があるのに忘れていたようです。

ということで次のコードを足して、ワーニングを解消することができました。

coverView.translatesAutoresizingMaskIntoConstraints = false
messageLabel.translatesAutoresizingMaskIntoConstraints = false

補足

全てのワーニングが解析できるかというとそうでもないようです。
スクリーンショット 2018-08-26 18.51.54.png

まとめ

  • どんな制約が絡み合っているのかを確認したい場合はWhy The Failure, Auto Layout?を使うと便利
  • identifierを付けるともっとわかりやすくなる
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
63
Help us understand the problem. What are the problem?