あいまいなレイアウト
あいまいなレイアウトは、制約のシステムに 2 つ以上の有効な解決策がある場合に発生します。主な原因は 2 つあります。
- すべてのビューの位置と場所を一意に指定するには、レイアウトに追加の制約が必要です。
- レイアウトに同じ優先度の矛盾するオプションの制約があり、システムはどの制約を解除するかを認識していません。
あいまいなビューを特定したら、制約を追加して、ビューの位置とサイズの両方を一意に指定します。
ここでは、優先度を変更してそれらが等しくなくなるようにして、どの制約を解除するかをシステムに通知する必要があります。システムは、優先度が最も低い制約を最初に解除します。
あいまいなレイアウトの検出
満たされないレイアウトと同様に、Interface Builder は設計時に、あいまいなレイアウトを検出し、修正する提案を提供できます。これらのあいまいさは、問題ナビゲータの警告、ドキュメントのアウトラインのエラー、キャンバス内の赤い線として表示されます。詳細については、満たされない制約の特定 を参照してください。
満たされないレイアウトと同様に、Interface Builder はすべての可能なあいまいさを検出することはできません。多くのエラーは、テストによってのみ見つけることができます。
実行時にあいまいなレイアウトが発生した場合、自動レイアウトは使用可能な解決策の 1 つを選択します。つまり、レイアウトは期待どおりに表示される場合とされない場合があるという意味です。さらに、コンソールには警告が表示されず、あいまいなレイアウトにブレークポイントを設定する方法もありません。
その結果、あいまいなレイアウトは、満たされないレイアウトよりも検出と識別が困難になることがよくあります。あいまいさが明白で目に見える影響を与える場合でも、エラーがあいまいさによるものか、レイアウト論理のエラーによるものかを判断するのは難しい場合があります。
幸い、あいまいなレイアウトを特定するために呼び出すことができるメソッドがいくつかあります。これらのメソッドはすべて、デバッグにのみ使用してください。ビュー階層にアクセスできる場所にブレークポイントを設定し、コンソールから以下のいずれかのメソッドを呼び出します。
- hasAmbiguousLayout. iOS と OS X の両方で使用できます。誤った場所にあるビューでこのメソッドを呼び出します。ビューのフレームがあいまいな場合は、YES を返します。それ以外の場合は、NO を返します。
- exerciseAmbiguityInLayout. iOS と OS X の両方で使用できます。あいまいなレイアウトのビューでこのメソッドを呼び出します。これにより、システムが有効な解決策間を切り替えます。
- constraintAffectingLayoutForAxis:. iOS で使用できます。このメソッドをビューで呼び出します。指定された軸に沿ってそのビューに影響を与えるすべての制約の配列を返します。
- constraintAffectingLayoutForOrientation:. OS X で使用できます。このメソッドをビューで呼び出します。指定された向きに沿ってそのビューに影響を与えるすべての制約の配列を返します。
- _autolayoutTrace. iOS では private メソッドとして使用できます。このメソッドをビューで呼び出します。そのビューを含むビュー階層全体に関する診断情報の文字列を返します。あいまいなビューにはラベルが付けられ、translatesAutoresizingMaskIntoConstraints が YES に設定されているビューにもラベルが付けられます。
これらのコマンドをコンソールで実行するときは、Objective-C 構文を使用する必要がある事があります。たとえば、ブレークポイントが実行を停止した後、コンソールウィンドウに call [self.myView exerciseAmbiguityInLayout] と入力し、exerciseAmbiguityInLayout メソッドを、myView オブジェクト上で呼び出します。同様に、po [self.myView autolayoutTrace] と入力して、myView を含むビュー階層に関する診断情報を出力します。
上記の診断メソッドを実行する前に、Interface Builder で見つかった問題を全て必ず修正してください。Interface Builder は、検出した全てのエラーの修復を試みます。つまり、あいまいなレイアウトが見つかると、制約が追加され、レイアウトがあいまいでなくなります。
その結果、hasAmbiguousLayout は NO を返します。exerciseAmbiguityInLayout は効果がないように見え、constraintsAffectingLayoutForAxis: は追加の予期しない制約を返します。
前:満たされないレイアウト 次:論理的なエラー