満たされないレイアウト
システムが現在の制約のセットに対する有効な解決策を見つけられない場合、満たされないレイアウトが発生します。2 つ以上の必須制約が同時に真にはならないため、矛盾します。
満たされない制約の特定
多くの場合、Interface Builder は設計時に矛盾を検出できます。このような場合、Interface Builder はいくつかの方法でエラーを表示します。
- 矛盾するすべての制約がキャンバスに赤で描かれます。
- Xcode は、問題ナビゲータ内に警告として矛盾する制約をリストします。
- Interface Builder は、ドキュメントのアウトラインの右上隅に赤い展開用矢印を表示します。
展開用矢印をクリックして、現在のレイアウトのすべての自動レイアウト問題のリストを表示します。
多くの場合、Interface Builder はこれらの問題の修正を推奨できます。詳細については、自動レイアウトヘルプの ビューコントローラー、ウィンドウ、またはルートビューのレイアウト問題の解決 を参照してください。
Interface Builder が提供する即時フィードバックにより、有効なレイアウトを作成するのがはるかに簡単になりますが、考えられるレイアウトエラーをすべて見つけることができるとは限りません。
たとえば、Interface Builder はキャンバスの現在のサイズでのみ矛盾を検出します。ただし、一部の矛盾は、ルートビューが特定のポイントを超えて拡大または縮小された場合 (またはコンテンツが特定のポイントを超えて拡大または縮小した場合) にのみ発生します。Interface Builder はこれらのエラーを検出できません。
したがって、Interface Builder が特定するすべての問題を常に修正する必要がありますが、明らかなエラーを修正するだけでは不十分です。引き続き、サポートしようとするスクリーンサイズ、向き、動的タイプサイズ、および言語の全範囲にわたって実行時のテストを実行する必要があります。
システムが実行時に満たされないレイアウトを検出すると、以下の手順を実行します。
- 自動レイアウトは、矛盾する制約のセットを識別します。
- 矛盾する制約の 1 つを解除し、レイアウトをチェックします。システムは、有効なレイアウトが見つかるまで制約を解除し続けます。
- 自動レイアウトは、矛盾と解除された制約に関する情報をコンソールに記録します。
この代わりになるシステムは、ユーザーに意味のある何かを提示しようとしながら、アプリを続行させます。ただし、制約を解除する影響は、レイアウトごと、またはビルドごとに大きく異なります。
多くの場合、不足している制約は目に見える影響を与えない場合があります。ビュー階層が完全に期待どおりに表示されます。他の場合では、制約がないために、ビュー階層のセクション全体が誤った場所に配置されたり、サイズが誤ったり、完全に消えたりすることがあります。
エラーが明らかな影響を与えない場合は、エラーを無視したくなることがよくあります。結局のところ、アプリの動作は変更されません。ただし、ビュー階層または SDK に何か変更を加えると、一連の解除された制約が変更され、明らかに壊れたレイアウトが突然作成されます。
したがって、満たされない制約エラーを検出したら、常に修正してください。テスト中に自明ではないエラーを確実にキャッチするには、UIViewAlertForUnsatisfiableConstraints にシンボリックブレークポイントを設定します。
満たされない制約の防止
満たされない制約は比較的簡単に修正できます。システムは、満たされない制約が発生すると通知し、矛盾する制約のリストを提供します。
エラーについて知ったらすぐに、解決策は通常非常に簡単です。制約の 1 つを削除するか、オプションの制約に変更してください。
ただし、さらに詳しく調べる価値があるいくつかの一般的な問題があります。
- プログラムによってビュー階層にビューを追加するときに、満たされない制約が発生することがよくあります。
- ビュー階層が小さすぎるスペースに表示されている場合、満たされない制約が発生することがよくあります。
デフォルトでは、新しいビューの translatesAutoresizingMaskIntoConstraints プロパティは YES に設定されています。キャンバス内のビューに制約を描画し始めると、Interface Builder はこのプロパティを自動的に NO に設定します。ただし、プログラムでビューを作成してレイアウトする場合は、独自のカスタム制約を追加する前に、プロパティを NO に設定する必要があります。
通常、ビューがアクセスできるスペースの最小量を予測して、レイアウトを適切に設計できます。ただし、国際化と動的タイプの両方により、ビューのコンテンツが予想よりはるかに大きくなる可能性があります。可能な順列の数が増えると、レイアウトがすべての状況で機能することを保証することがますます難しくなります。
代わりに、障害点を組み込んで、予測可能な制御された方法でレイアウトが失敗するようにすることができます。
必須の制約の一部を優先度の高いオプションの制約に変換することを検討してください。これらの制約により、矛盾が発生したときにレイアウトがどこで壊れるかを制御できます。
たとえば、障害ポイントの優先度を 999 にします。ほとんどの状況では、この高優先度の制約は、必須であるかのように機能します。ただし、矛盾が発生すると、優先度の高い制約が解除され、レイアウトの残りの部分が保護されます。
同様に、固有のコンテンツサイズのビューに、必須のコンテンツハグまたは圧縮耐性の優先度を与えることは避けてください。通常、コントロールのサイズは理想的な障害点として機能します。レイアウトに意味のある影響を与えることなく、コントロールを少し大きくしたり、少し小さくしたりできます。
さあ、固有のコンテンツサイズでのみ表示する必要があるコントロールがあります。ただし、これらの場合でも、通常、レイアウトを予測できない方法で解除するだけでなく、数ポイント離れたコントロールを使用することをお勧めします。