デバッグの秘訣とヒント


以下のトピックスでは、レイアウトに関する情報を収集・整理する方法と、発生する可能性があるいくつかの驚くべき動作について説明します。すべてのレイアウトでこれらのテクニックを使用する必要はないかもしれませんが、最も困難な問題を解決するのに役立ちます。


ログの理解


ビューに関する情報は、満たされないレイアウトがあるか、constraintsAffectingLayoutForAxis: または constraintAffectingLayoutForOrientation: デバッグメソッドを使用して制約を明示的にログに記録したため、コンソールに出力できます。


どちらの方法でも、これらのログで多くの有用な情報を見つけることができます。以下に、満たされないレイアウトエラーの出力例を示します。


 1    2015-08-26 14:27:54.790 Auto Layout Cookbook[10040:1906606] Unable to simultaneously 
 		satisfy constraints.
 2        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) 
 3    (
 4        "<NSLayoutConstraint:0x7a87b000 H:[UILabel:0x7a8724b0'Name'(>=400)]>",
 5        "<NSLayoutConstraint:0x7a895e30 UILabel:0x7a8724b0'Name'.leading == 
 			UIView:0x7a887ee0.leadingMargin>",
 6        "<NSLayoutConstraint:0x7a886d20 H:[UILabel:0x7a8724b0'Name']-(NSSpace(8))-[
 			UITextField:0x7a88cff0]>",
 7        "<NSLayoutConstraint:0x7a87b2e0 UITextField:0x7a88cff0.trailing == 
 			UIView:0x7a887ee0.trailingMargin>",
 8        "<NSLayoutConstraint:0x7ac7c430 'UIView-Encapsulated-Layout-Width' 
 			H:[UIView:0x7a887ee0(320)]>"
 9    )
10     
11    Will attempt to recover by breaking constraint
12    <NSLayoutConstraint:0x7a87b000 H:[UILabel:0x7a8724b0'Name'(>=400)]>
13     
14    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this 
		in the debugger.
15    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in
 <UIKit/UIView.h> may also be helpful.


このエラーメッセージは、5 つの矛盾する制約を示しています。これらの制約のすべてが同時に当てはまるわけではありません。その 1 つを削除するか、オプションの制約に変換する必要があります。


幸い、ビュー階層は比較的単純です。ラベルとテキストフィールドを含むスーパービューがあります。矛盾する制約により、以下の関係が設定されます。


  1. ラベルの幅は 400 ポイント以上です。
  2. ラベルの先端は、スーパービューの先端マージンと同じです。
  3. ラベルとテキストフィールドの間に 8 ポイントのスペースがあります。
  4. テキストフィールドの後端は、スーパービューの後端マージンと同じです。
  5. スーパービューの幅は 320 ポイントに設定されています。

システムは、ラベルの幅を解除して回復を試みます。


注意:

制約は、Visual Format Language を使用してコンソールに書き込まれます。視覚書式言語 (Visual Format Language) を使用して独自の制約を作成したことが全くない場合でも、自動レイアウトの問題を効果的にデバッグするには、それを読んで理解できなければなりません。詳細については、視覚書式言語 を参照してください。




これらの制約のうち、最後の制約はシステムによって作成されました。変更することはできません。さらに、最初の制約との明らかな矛楯が発生します。スーパービューの幅が 320 ポイントしかない場合、400 ポイント幅のラベルを付けることはできません。幸い、最初の制約を取り除く必要はありません。優先度を 999 に下げても、システムはまだ選択された幅を提供しようとしますが、他の制約も満たしながら、可能な限り近くなります。


ビューの自動サイズ変更マスクに基づく制約 (たとえば、translatesAutoresizingMaskIntoConstraintsYES の場合に作成される制約) には、マスクに関する追加情報があります。制約のアドレスの後、ログ文字列には h= の後に 3 文字が続き、v= の後に 3 文字が続きます。- (ハイフン) 文字は固定値を示し、& (アンパサンド) は柔軟な値を示します。水平マスク (h=) の場合、3 つの文字は左マージン、幅、および右マージンを示します。垂直マスク (v=) の場合、上マージン、高さ、下マージンを示します。


例えば、ログメッセージについて考えてみます。


	<NSAutoresizingMaskLayoutConstraint:0x7ff28252e480 h=--& v=--& 
		H:[UIView:0x7ff282617cc0(50)]>"


このメッセージは以下の部分で構成されています。


ログへの ID の追加


前の例は比較的理解しやすいものでしたが、制約のリストが長くなると、従うことがすぐに難しくなります。すべてのビューと制約に意味のある ID を提供することで、ログを読みやすくすることができます。


ビューに明白なテキストコンポーネントがある場合、Xcode はそれを ID として使用します。たとえば、Xcode はラベルのテキスト、ボタンのタイトル、またはテキストフィールドのプレースホルダを使用して、これらのビューを識別します。それ以外の場合は、ID インスペクタでビューの Xcode 固有のラベルを設定します。Interface Builder は、インターフェイス全体でこれらの ID を使用します。それらの多くは、コンソールログにも表示されます。


制約については、プログラムで、または属性インスペクタを使用して、それらの identifier プロパティを設定します。その後自動レイアウトは、コンソールに情報を出力するときにこれらの ID を使用します。


たとえば、ID を設定した場合と同じ満たされない制約エラーは以下のとおりです。


 1    2015-08-26 14:29:32.870 Auto Layout Cookbook[10208:1918826] Unable to simultaneously 
 		satisfy constraints.
 2        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) 
 3    (
 4        "<NSLayoutConstraint:0x7b58bac0 'Label Leading' UILabel:0x7b58b040'Name'.leading 
 		== UIView:0x7b590790.leadingMargin>",
 5        "<NSLayoutConstraint:0x7b56d020 'Label Width' 
 		H:[UILabel:0x7b58b040'Name'(>=400)]>",
 6        "<NSLayoutConstraint:0x7b58baf0 'Space Between Controls' 
 		H:[UILabel:0x7b58b040'Name']-(NSSpace(8))-[UITextField:0x7b589490]>",
 7        "<NSLayoutConstraint:0x7b51cb10 'Text Field Trailing' 
 		UITextField:0x7b589490.trailing == UIView:0x7b590790.trailingMargin>",
 8        "<NSLayoutConstraint:0x7b0758c0 'UIView-Encapsulated-Layout-Width' 
 		H:[UIView:0x7b590790(320)]>"
 9    )
10     
11    Will attempt to recover by breaking constraint
12    <NSLayoutConstraint:0x7b56d020 'Label Width' H:[UILabel:0x7b58b040'Name'(>=400)]>
13     
14    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this 
		in the debugger.
15    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in 
		<UIKit/UIView.h> may also be helpful.


ご覧のとおり、これらの ID を使用すると、ログ内の制約をすばやく簡単に認識することができます。



ビューと制約の視覚化


Xcode は、ビューとビュー階層の制約を視覚化するのに役立つツールを提供します。


シミュレーターでビューを表示するには:


  1. シミュレーターでアプリを実行します。

  2. Xcode に切り替えます。

  3. [デバッグ(Debug)] > [デバッグの表示(View Debug)] > [四角形を整列して表示(Show Alignment Rectangles)] を選択します。この設定は、ビューのエッジの輪郭を描きます。

Show_Alignment_Rectangles_2x



整列した長方形は、自動レイアウトで使用されるエッジです。このオプションをオンにすると、予期せずサイズ変更された整列した長方形をすばやく見つけることができます。


さらに詳しい情報が必要な場合は、Xcode デバッグバーの [デバッグビュー階層(Debug View Hierarchy)] ボタン (Screen_Shot)をクリックします。次に、Xcode はインタラクティブなビューデバッガーを表示し、ビュー階層を探索および操作するための多数のツールを提供します。自動レイアウトの問題をデバッグする場合、"クリップされたコンテンツを表示する" および "制約を表示する" オプションが特に役立ちます。


Debug_View_Hierarchy_2x



"クリップされたコンテンツを表示" オプションを有効にすると、誤ってスクリーンの外に配置されたビューの場所が表示されます。"制約を表示" オプションを有効にすると、現在選択されているビューに影響を与えるすべての制約が表示されます。どちらのオプションとも、異常な動作が始まったときに迅速な健全性チェックを提供します。


詳細については、デバッグ領域のヘルプ を参照してください。


極端な場合の理解


自動レイアウトが予期しない方法で動作する原因となるいくつかの極端なケースを以下に示します。


前:論理的なエラー 次:プログラムによる制約の作成
































































目次
Xcode の新機能

  • 始めましょう

  • 自動レイアウトガイド全メニュー

  • 自動レイアウトレシピ集

  • 自動レイアウトのデバッグ

  • エラーの型
  • 満たされないレイアウト
  • あいまいなレイアウト
  • 論理的なエラー
  • デバッグの秘訣とヒント
  • ログの理解
    ログへの ID の追加
    ビューと制約の視覚化
    端の場合の理解

  • 高度な自動レイアウト

  • 付録

  • 改訂記録











  • トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ