次の方法で共有


Xamarin.iOS のスタック ビュー

この記事では、Xamarin.iOS アプリで新しい UIStackView コントロールを使用して、水平方向または垂直方向に配置されたスタックで一連のサブビューを管理する方法について説明します。

重要

iOS Designer では StackView がサポートされていますが、安定チャネルの使用時に使いやすさのバグが発生する可能性があることに注意してください。 ベータまたはアルファ チャネルを切り替えると、この問題が軽減されます。 必要な修正プログラムが安定チャネルに実装されるまで、Xcode を使用してこのチュートリアルを紹介することにしました。

スタック ビュー コントロール (UIStackView) は、自動レイアウトとサイズ調整クラスの機能を利用して、iOS デバイスの向きと画面サイズに動的に対応するサブビューのスタック (水平方向または垂直方向) を管理します。

スタック ビューにアタッチされているすべてのサブビューのレイアウトは、軸、分布、配置、間隔などの開発者が定義したプロパティに基づいてスタック ビューによって管理されます。

スタック ビューのレイアウト図

Xamarin.iOS アプリで UIStackView を使用する場合、開発者は、iOS Designer のストーリーボード内で、または C# コードでサブビューを追加および削除することで、サブビューを定義できます。

このドキュメントは、最初のスタック ビューの実装に役立つクイック スタートと、その動作に関する技術的な詳細の 2 つの部分で構成されています。

UIStackView ビデオ

UIStackView クイック スタート

UIStackView コントロールの簡単な紹介として、ユーザーが 1 から 5 で評価を入力できるシンプルなインターフェイスを作成する予定です。 2 つのスタック ビューを使用します。1 つはデバイスの画面上でインターフェイスを垂直方向に配置し、もう 1 つは 1 から 5 の評価アイコンを画面全体に水平方向に配置します。

UI を定義する

新しい Xamarin.iOS プロジェクトを開始し、Xcode の Interface Builder で Main.storyboard ファイルを編集します。 最初に、View Controller で 1 つの垂直スタック ビューをドラッグします。

ビュー コントローラーで 1 つの垂直スタック ビューをドラッグする

[Attribute Inspector]で、次のオプションを設定します。

スタック ビューのオプションを設定する

ここで:

  • Axis – スタック ビューによってサブビューが水平方向または垂直方向に配置されるかどうかを決定します。
  • 配置 – スタック ビュー内でのサブビューの配置方法を制御します。
  • 分布 – スタック ビュー内でサブビューのサイズを設定する方法を制御します。
  • Spacing – スタック ビュー内での各サブビュー間の最小スペースを制御します。
  • Baseline Relative – オンにした場合、各サブビューの垂直方向のスペースは、そのベースラインから派生します。
  • Layout Margins Relative – 標準レイアウトの余白を基準にサブビューを配置します。

スタック ビューを使用する場合、[Alignment] はサブビューの XY の位置、[Distribution]高さとして考えることができます。

重要

UIStackView は、非レンダリング コンテナー ビューとして設計されているため、UIView のその他のサブクラスとは異なり、キャンバスに描画されません。 そのため、BackgroundColor などのプロパティを設定したり、DrawRect をオーバーライドしたりしても、視覚的な効果はありません。

次のようになるように、ラベル、イメージビュー、2 つのボタン、水平スタック ビューを追加して、アプリのインターフェイスのレイアウトを続けます。

スタック ビュー UI のレイアウト

次のオプションを使用して、水平スタック ビューを構成します。

[水平スタック ビュー] オプションを構成する

評価の各 "ポイント" を表すアイコンが水平スタック ビューに追加されたときに伸縮されないようにするために、[Alignment][Center] に、[Distribution][Fill Equally] に設定しました。

最後に、次の OutletsActions を接続します。

スタック ビューのアウトレットとアクション

コードから UIStackView を設定する

Visual Studio for Mac に戻り、ViewController.cs ファイルを編集して次のコードを追加します。

public int Rating { get; set;} = 0;
...

partial void IncreaseRating (Foundation.NSObject sender) {

    // Maximum of 5 "stars"
    if (++Rating > 5 ) {
        // Abort
        Rating = 5;
        return;
    }

    // Create new rating icon and add it to stack
    var icon = new UIImageView (new UIImage("icon.png"));
    icon.ContentMode = UIViewContentMode.ScaleAspectFit;
    RatingView.AddArrangedSubview(icon);

    // Animate stack
    UIView.Animate(0.25, ()=>{
        // Adjust stack view
        RatingView.LayoutIfNeeded();
    });

}

partial void DecreaseRating (Foundation.NSObject sender) {

    // Minimum of zero "stars"
    if (--Rating < 0) {
        // Abort
        Rating =0;
        return;
    }

    // Get the last subview added
    var icon = RatingView.ArrangedSubviews[RatingView.ArrangedSubviews.Length-1];

    // Remove from stack and screen
    RatingView.RemoveArrangedSubview(icon);
    icon.RemoveFromSuperview();

    // Animate stack
    UIView.Animate(0.25, ()=>{
        // Adjust stack view
        RatingView.LayoutIfNeeded();
    });
}

このコードのいくつかの部分を詳しく見てみましょう。 まず、if ステートメントを使用して、"星" の数が 5 より大きくないか、または 0 より小さくないかを確認します。

新しい "星" を追加するには、そのイメージを読み込み、Content ModeScale Aspect Fit に設定します。

var icon = new UIImageView (new UIImage("icon.png"));
icon.ContentMode = UIViewContentMode.ScaleAspectFit;

これにより、"星" アイコンがスタック ビューに追加されたときに歪むことを防止できます。

次に、新しい "星" アイコンをスタック ビューのサブビューのコレクションに追加します。

RatingView.AddArrangedSubview(icon);

UIImageViewUIStackViewSubView ではなく ArrangedSubviews プロパティに追加したことに注意してください。 スタック ビューでレイアウトを制御するビューは、ArrangedSubviews プロパティに追加する必要があります。

スタック ビューからサブビューを削除するには、まず、削除するサブビューを取得します。

var icon = RatingView.ArrangedSubviews[RatingView.ArrangedSubviews.Length-1];

次に、それを ArrangedSubviews コレクションとスーパー ビューの両方から削除する必要があります。

// Remove from stack and screen
RatingView.RemoveArrangedSubview(icon);
icon.RemoveFromSuperview();

ArrangedSubviews コレクションだけからサブビューを削除した場合、スタック ビューのコントロールからは外れますが、画面からは削除されません。

UI のテスト

必要なすべての UI 要素とコードを配置したので、インターフェイスを実行してテストできるようになりました。 UI が表示されると、垂直スタック ビュー内のすべての要素が上から下に等間隔に配置されます。

ユーザーが [Increase Rating] ボタンをタップすると、新たな "星" が画面に追加されます (最大 5 つまで)。

サンプル アプリの実行

"星" は自動的に中央に配置され、水平スタック ビューで均等に分散されます。 ユーザーが [Decrease Rating] ボタンをタップすると、"星" が 1 つずつ (すべて消えるまで) 削除されます。

スタック ビューの詳細

これで、UIStackView コントロールの概要と動作について確認したので、その機能と詳細についてさらに詳しく見ていきましょう。

自動レイアウトおよびサイズ クラス

前述のように、サブビューをスタック ビューに追加すると、配置されたビューを配置およびサイズ変更するために、そのレイアウトが自動レイアウト クラスとサイズ クラスを使用してスタック ビューによって完全に制御されます。

スタック ビューでは、コレクション内の最初と最後のサブビューが、垂直スタック ビューの場合は端と端、水平スタック ビューの場合は端と端に "ピン留め" されます。 LayoutMarginsRelativeArrangement プロパティを true に設定すると、サブビューは端ではなく、関連する余白にピン留めされます。

スタック ビューでは、定義された Axis に沿ったサブビューのサイズを計算するときにサブビューの IntrinsicContentSize プロパティが使用されます (FillEqually Distribution は除きます)。 FillEqually Distribution の場合、すべてのサブビューのサイズが同じになるようにサイズが変更され、これにより、Axis に沿ってスタック ビューが塗りつぶされます。

Fill Alignment を除き、スタック ビューでは、指定された Axis ビューに対して垂直なビューのサイズを計算するためにサブビューの IntrinsicContentSize プロパティが使用されます。 Fill Alignment の場合、すべてのサブビューによって指定されたAxis に対して垂直なスタック ビューが塗りつぶされるように、これらのサブビューのサイズが設定されます。

スタック ビューの配置とサイズ設定

サブビューのレイアウトは (AxisDistribution などのプロパティに基づいて) スタック ビューによって完全に制御されますが、ユーザーは依然として、自動レイアウト クラスとサイズ クラスを使用して親ビュー内にスタック ビュー (UIStackView) を配置する必要があります。

一般に、これは、スタック ビューの少なくとも 2 つの端をピン留めして拡大および縮小し、その位置を定義することを意味します。 追加の制約がない場合、スタック ビューは次のように、すべてのサブビューをサイズに合わせて調整するために自動的にサイズ変更されます。

  • Axis に沿ったサイズは、すべてのサブビューのサイズの合計に、各サブビュー間で定義されたスペースを足した値になります。
  • LayoutMarginsRelativeArrangement プロパティが true である場合、スタック ビューのサイズには余白のスペースも含まれます。
  • Axis に対して垂直なサイズは、コレクション内の最大サブビューに設定されます。

また、スタック ビューの高さの制約を指定することもできます。 この場合、サブビューは、Distribution および Alignment プロパティによって決定されたとおりにスタック ビューによって指定されたスペースを塗りつぶすようにレイアウト (サイズ設定) されます。

BaselineRelativeArrangement プロパティが true である場合、サブビューは、、または中心- Y の位置ではなく、最初または最後のサブビューのベースラインに基づいてレイアウトされます。 これらは、次のようにスタック ビューのコンテンツで計算されます。

  • 垂直スタック ビューにより、最初のベースラインに対して最初のサブビュー、および最後のベースラインに対して最後のサブビューが返されます。 これらのいずれかのサブビュー自体がスタック ビューである場合は、最初または最後のベースラインが使用されます。
  • 水平スタック ビューにより、最初のベースラインと最後のベースラインの両方に対して最も高いサブビューが使用されます。 最も高いビューがスタック ビューでもある場合は、最も高いサブビューがベースラインとして使用されます。

重要

ベースラインの配置は、拡大または圧縮されたサブビューのサイズに対しては機能しません。なぜなら、ベースラインの計算結果が間違った位置になるからです。 ベースライン配置の場合、サブビューの高さが組み込みコンテンツ ビューの高さと一致していることを確認します。

一般的なスタック ビューの用途

スタック ビュー コントロールで適切に動作するレイアウトの種類がいくつかあります。 Apple によると、いくつかの一般的な用途には次のものがあります。

  • 軸に沿ったサイズの定義 – スタック ビューの Axis に沿って両方の端をピン留めし、隣接する端の 1 つを固定して位置を設定することで、サブビューで定義されたスペースに合うようにスタック ビューが軸に沿って拡大されます。
  • サブビューの位置の定義 – スタック ビューの隣接する端を親ビューにピン留めすることで、スタック ビューは、含まれるサブビューに合うように両方向に拡大されます。
  • スタック ビューのサイズと位置の定義 – スタック ビューの4つの端をすべて親ビューにピン留めすることで、スタック ビューによってスタック ビュー内で定義されたスペースに基づいてサブビューが配置されます。
  • 軸に垂直なサイズの定義 – スタック ビューの Axis に垂直な両方の端と、軸に沿った端の 1 つエッジをピン留めして位置を設定することで、スタック ビューはサブビューで定義されたスペースに合わせて軸に垂直に拡大されます。

外観の管理

UIStackView は、非レンダリング コンテナー ビューとして設計されているため、UIView のその他のサブクラスとは異なり、キャンバスに描画されません。 BackgroundColor などのプロパティを設定しても、DrawRect をオーバーライドしても、視覚的な効果はありません。

スタック ビューでサブビューのコレクションを配置する方法を制御するプロパティがいくつかあります。

  • – スタック ビューによってサブビューが水平方向または垂直方向に配置されるかどうかを決定します。
  • 配置 – スタック ビュー内でのサブビューの配置方法を制御します。
  • 分布 – スタック ビュー内でサブビューのサイズを設定する方法を制御します。
  • 間隔 – スタック ビュー内の各サブビュー間の最小スペースを制御します。
  • ベースライン基準true である場合、各サブビューの垂直方向の間隔は、そのベースラインから派生します。
  • レイアウト余白基準 – 標準レイアウトの余白を基準にサブビューを配置します。

通常、スタック ビューを使用して、少数のサブビューを配置します。 1 つ以上のスタック ビューを相互に入れ子にすることで、より複雑なユーザー インターフェイスを作成できます (上記の UIStackView クイック スタートで行ったように)。

サブビューに制約を追加することで、UI の外観をさらに微調整できます (たとえば、高さや幅を制御できます)。 ただし、スタック ビュー自体によって導入されたサブビューに競合する制約を含めないように注意する必要があります。

配置ビューとサブビューの整合性の維持

スタック ビューでは、次の規則を使用して、Subviews プロパティが常に ArrangedSubviews プロパティのサブセットであるようにします。

  • ArrangedSubviews コレクションに追加されたサブビューは、自動的に Subviews コレクションに追加されます (そのコレクションに既に含まれている場合を除く)。
  • Subviews コレクションから削除 (表示から削除) されたサブビューは、ArrangedSubviews コレクションからも削除されます。
  • サブビューを ArrangedSubviews コレクションから削除しても、Subviews コレクションからは削除されません。 そのため、スタック ビューによってレイアウトされなくなりますが、画面には引き続き表示されます。

ArrangedSubviews コレクションは常に Subview コレクションのサブセットですが、各コレクション内の個々のサブビューの順序は、以下によって個別に制御されます。

  • ArrangedSubviews コレクション内のサブビューの順序によって、スタック内での表示順序が決まります。
  • Subview コレクション内のサブビューの順序によって、ビュー内の Z オーダー (またはレイヤー化) が決まります (後ろから前)。

コンテンツを動的に変更する

スタック ビューでは、サブビューが追加、削除、または非表示になるたびに、サブビューのレイアウトが自動的に調整されます。 スタック ビューのいずれかのプロパティ (Axis など) を調整すると、レイアウトも調整されます。

レイアウトの変更は、アニメーション ブロック内に配置することでアニメーション化できます。次に例を示します。

// Animate stack
UIView.Animate(0.25, ()=>{
    // Adjust stack view
    RatingView.LayoutIfNeeded();
});

スタック ビューのプロパティの多くは、ストーリーボード内のサイズ クラスを使用して指定できます。 これらのプロパティは、サイズや向きの変更に応じて自動的にアニメーション化されます。

まとめ

この記事では、Xamarin.iOS アプリで水平方向または垂直方向に配置されたスタックで一連のサブビューを管理するための新しい UIStackView コントロール (iOS 9 用) について説明しました。 スタック ビューを使用して UI を作成する簡単な例から始まり、スタック ビューとそのプロパティおよび機能について詳しく説明しました。