Xamarin.iOS でのプログラムによるレイアウト制約

このガイドでは、iOS Designerで作成するのではなく、C# コードで iOS 自動レイアウト制約を使用する方法について説明します。

自動レイアウト ("アダプティブ レイアウト" とも呼ばれます) は、応答性の高い設計アプローチです。 各要素の位置が画面上のポイントにハードコーディングされている移行レイアウト システムとは異なり、自動レイアウトは リレーションシップ に関するものです。これは、デザインサーフェイス上の他の要素に対する要素の位置です。 自動レイアウトの中心となるのは、画面上の他の要素のコンテキストにおける要素または要素のセットの配置を定義する制約またはルールの概念です。 要素は画面上の特定の位置に関連付けられていないため、制約は、さまざまな画面サイズとデバイスの向きに適したアダプティブ レイアウトを作成するのに役立ちます。

通常、iOS で自動レイアウトを使用する場合は、Xcode のインターフェイス ビルダーを使用して、UI 項目にレイアウト制約をグラフィカルに配置します。 ただし、C# コードで制約を作成して適用する必要がある場合があります。 たとえば、 に追加された動的に作成された UI 要素を使用する場合です UIView

このガイドでは、Xcode の Interface Builder でグラフィカルに作成するのではなく、C# コードを使用して制約を作成して操作する方法について説明します。

プログラムによる制約の作成

上記のように、通常は iOS Designerで自動レイアウト制約を使用します。 プログラムで制約を作成する必要がある場合は、次の 3 つのオプションから選択できます。

  • Layout Anchors - この API は、制約されている UI 項目のアンカー プロパティ (、 HeightAnchorBottomAnchor などTopAnchor) へのアクセスを提供します。
  • レイアウト制約 - クラスを使用して制約を NSLayoutConstraint 直接作成できます。
  • Visual Formatting Language - 制約を定義するメソッドのような ASCII アートを提供します。

次のセクションでは、各オプションについて詳しく説明します。

レイアウト アンカー

クラスを NSLayoutAnchor 使用すると、制約対象の UI 項目のアンカー プロパティに基づいて制約を作成するための fluent インターフェイスが用意されています。 たとえば、ビュー コントローラーの上下のレイアウト ガイドでは、 BottomAnchor プロパティとアンカー プロパティがTopAnchor公開されHeightAnchor、View ではエッジ、中央、サイズ、ベースラインの各プロパティが公開されます。

重要

iOS ビューには、アンカー プロパティの標準セットに加えて、 LayoutMarginsGuides プロパティと ReadableContentGuide プロパティも含まれています。 これらのプロパティは、ビューの余白と読み取り可能なコンテンツ ガイドをそれぞれ操作するためのオブジェクトを公開 UILayoutGuide します。

Layout Anchors には、読みやすいコンパクトな形式で制約を作成するためのいくつかの方法が用意されています。

  • ConstraintEqualTo - 必要に応じて指定されたconstantオフセット値を持つ リレーションシップfirst attribute = second attribute + [constant]を定義します。
  • ConstraintGreaterThanOrEqualTo - 必要に応じて指定されたconstantオフセット値を持つ リレーションシップfirst attribute >= second attribute + [constant]を定義します。
  • ConstraintLessThanOrEqualTo - 必要に応じて指定されたconstantオフセット値を持つ リレーションシップfirst attribute <= second attribute + [constant]を定義します。

次に例を示します。

// Get the parent view's layout
var margins = View.LayoutMarginsGuide;

// Pin the leading edge of the view to the margin
OrangeView.LeadingAnchor.ConstraintEqualTo (margins.LeadingAnchor).Active = true;

// Pin the trailing edge of the view to the margin
OrangeView.TrailingAnchor.ConstraintEqualTo (margins.TrailingAnchor).Active = true;

// Give the view a 1:2 aspect ratio
OrangeView.HeightAnchor.ConstraintEqualTo (OrangeView.WidthAnchor, 2.0f);

一般的なレイアウト制約は、線形式として単純に表すことができます。 次の例を参照してください。

線形式として表されるレイアウト制約

これは、Layout Anchors を使用して次の C# コード行に変換されます。

PurpleView.LeadingAnchor.ConstraintEqualTo (OrangeView.TrailingAnchor, 10).Active = true; 

ここで、C# コードの部分は、次のように式の指定された部分に対応します。

方程式 コード
アイテム 1 PurpleView
属性 1 LeadingAnchor
リレーションシップ ConstraintEqualTo
乗数 既定値は 1.0 であるため、指定されていません
項目 2 OrangeView
属性 2 TrailingAnchor
常時 10.0

特定のレイアウト制約式を解決するために必要なパラメーターのみを指定するだけでなく、各 Layout Anchor メソッドでは、渡されるパラメーターの型セーフが適用されます。 そのため、 や TrailingAnchor などのLeadingAnchor水平制約アンカーは、他の水平アンカーの種類でのみ使用でき、乗数はサイズ制約にのみ提供されます。

レイアウトの制約

C# コードで を直接構築することで、自動レイアウト制約を NSLayoutConstraint 手動で追加できます。 Layout Anchors の使用とは異なり、定義されている制約に影響を与えない場合でも、すべてのパラメーターに値を指定する必要があります。 その結果、かなりの量の読みにくい定型コードが生成されます。 次に例を示します。

//// Pin the leading edge of the view to the margin
NSLayoutConstraint.Create (OrangeView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, View, NSLayoutAttribute.LeadingMargin, 1.0f, 0.0f).Active = true;

//// Pin the trailing edge of the view to the margin
NSLayoutConstraint.Create (OrangeView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, View, NSLayoutAttribute.TrailingMargin, 1.0f, 0.0f).Active = true;

//// Give the view a 1:2 aspect ratio
NSLayoutConstraint.Create (OrangeView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, OrangeView, NSLayoutAttribute.Width, 2.0f, 0.0f).Active = true;

ここで、NSLayoutAttribute列挙型はビューの余白の値を定義し、 などの TopRightLeftプロパティにLayoutMarginsGuide対応しNSLayoutRelationBottom、列挙型は、指定された属性間に作成されるリレーションシップを 、LessThanOrEqualまたは GreaterThanOrEqualとしてEqual定義します。

Layout Anchor API とは異なり、 NSLayoutConstraint 作成方法では特定の制約の重要な側面が強調表示されず、制約に対してコンパイル時チェックは実行されません。 その結果、実行時に例外をスローする無効な制約を簡単に構築できます。

Visual Format Language

Visual Format Language を使用すると、作成される制約を視覚的に表現する文字列などの ASCII アートを使用して制約を定義できます。 これには、次の長所と短所があります。

  • Visual Format Language では、有効な制約の作成のみが適用されます。
  • 自動レイアウトでは Visual Format Language を使用して制約がコンソールに出力されるため、デバッグ メッセージは制約の作成に使用されるコードのようになります。
  • Visual Format Language を使用すると、非常にコンパクトな式を使用して複数の制約を同時に作成できます。
  • Visual Format Language 文字列のコンパイル側検証がないため、問題は実行時にのみ検出できます。
  • Visual Format Language では完全性よりも視覚化が強調されるため、一部の制約型を使用して作成することはできません (比率など)。

Visual Format Language を使用して制約を作成する場合は、次の手順を実行します。

  1. NSDictionaryビュー オブジェクトとレイアウト ガイド、および書式を定義するときに使用される文字列キーを含む を作成します。
  2. 必要に応じて、 NSDictionary 制約の定数値として使用されるキーと値 (NSNumber) のセットを定義する を作成します。
  3. 1 列または 1 行の項目をレイアウトする書式指定文字列を作成します。
  4. クラスの メソッドをFromVisualFormatNSLayoutConstraint呼び出して制約を生成します。
  5. クラスの ActivateConstraints メソッドを NSLayoutConstraint 呼び出して、制約をアクティブ化して適用します。

たとえば、Visual Format Language で先頭と末尾の両方の制約を作成するには、次のコマンドを使用できます。

// Get views being constrained
var views = new NSMutableDictionary (); 
views.Add (new NSString ("orangeView"), OrangeView);

// Define format and assemble constraints
var format = "|-[orangeView]-|";
var constraints = NSLayoutConstraint.FromVisualFormat (format, NSLayoutFormatOptions.AlignAllTop, null, views);

// Apply constraints
NSLayoutConstraint.ActivateConstraints (constraints);

Visual Format Language では、既定の間隔を使用すると、常に親ビューの余白に 0 ポイント制約がアタッチされるため、このコードは上記の例と同じ結果を生成します。

1 行の複数の子ビューなど、より複雑な UI デザインの場合、Visual Format Language では、水平方向の間隔と垂直方向の配置の両方を指定します。 上の例のように、 を指定 AlignAllTopNSLayoutFormatOptions すると、行または列内のすべてのビューが上部に配置されます。

一般的な制約と Visual Format String Grammar を指定する例については、Apple の Visual Format Language 付録 を参照してください。

まとめ

このガイドでは、iOS Designerでグラフィカルに作成するのではなく、C# での自動レイアウト制約の作成と操作について説明しました。 最初に、Layout Anchors (NSLayoutAnchor) を使用して自動レイアウトを処理する方法を見てみましょう。 次に、レイアウト制約を操作する方法を示しました (NSLayoutConstraint)。 最後に、自動レイアウト用の Visual Format Language を使用して提示しました。