Xamarin.Mac でのストーリーボードの操作

ストーリーボードは、特定のアプリのすべての UI を、そのビュー コントローラーの機能的な概要に分割して定義します。 Xcode のインターフェイス ビルダーでは、これらの各コントローラーは独自のシーンに存在します。

A storyboard in Xcode's Interface Builder

ストーリーボードは、Xamarin.Mac アプリの .storyboardバンドルに含まれるリソース ファイル (拡張機能を含む) です。このファイルは、コンパイルされて配布されるときに含まれます。 アプリの開始ストーリーボードを定義するには、アプリの Info.plist ファイルを編集し、ドロップダウン ボックスから メイン インターフェイス を選択します。

The Info.plist editor

コードからの読み込み

コードから特定のストーリーボードを読み込み、ビュー コントローラーを手動で作成する必要がある場合があります。 次のコードを使用して、このアクションを実行できます。

// Get new window
var storyboard = NSStoryboard.FromName ("Main", null);
var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

// Display
controller.ShowWindow(this);

アプリ FromName のバンドルに含まれている特定の名前のストーリーボード ファイルが読み込まれます。 指定 InstantiateControllerWithIdentifier した ID を持つビュー コントローラーのインスタンスが作成されます。 UI の設計時に Xcode のインターフェイス ビルダーで ID を設定します。

Setting the Storyboard ID in Interface Builder.

必要に応じて、このメソッドを InstantiateInitialController 使用して、インターフェイス ビルダーで初期コントローラーが割り当てられているビュー コントローラーを読み込むことができます。

Setting the initial controller

ストーリー ボードのエントリ ポイント と、上のオープン終了矢印でマークされています。

コントローラーの表示

ビュー コントローラーは、Mac アプリ内の情報の特定のビューと、その情報を提供するデータ モデルの間の関係を定義します。 ストーリーボードの最上位の各シーンは、Xamarin.Mac アプリのコード内の 1 つのビュー コントローラーを表します。

ビュー コントローラーのライフサイクル

macOS でストーリーボードをサポートするために NSViewController 、いくつかの新しいメソッドがクラスに追加されました。 最も重要なのは、次のメソッドを使用して、指定されたビュー コントローラーによって制御されているビューのライフサイクルに応答することです。

  • ViewDidLoad - このメソッドは、ストーリーボード ファイルからビューが読み込まれるときに呼び出されます。
  • ViewWillAppear - このメソッドは、ビューが画面に表示される直前に呼び出されます。
  • ViewDidAppear - このメソッドは、ビューが画面に表示された直後に呼び出されます。
  • ViewWillDisappear - このメソッドは、ビューが画面から削除される直前に呼び出されます。
  • ViewDidDisappear - このメソッドは、ビューが画面から削除された直後に呼び出されます。
  • UpdateViewConstraints - ビューの自動レイアウト位置とサイズを定義する制約を更新する必要がある場合に、このメソッドが呼び出されます。
  • ViewWillLayout - このメソッドは、このビューのサブビューが画面にレイアウトされる直前に呼び出されます。
  • ViewDidLayout - このメソッドは、ビューのサブビューが画面にレイアウトされた直後に呼び出されます。

レスポンダー チェーン

さらに、 NSViewControllers ウィンドウの レスポンダー チェーンの一部になりました。

The Responder Chain

そのため、切り取り、コピー、貼り付けのメニュー項目の選択などのイベントを受け取り、応答するためにワイヤードアップされます。 この自動ビュー コントローラーのワイヤアップは、macOS Sierra (10.12) 以降で実行されているアプリでのみ行われます。

Containment

ストーリーボードでは、ビュー コントローラー (分割ビュー コントローラーやタブ ビュー コントローラーなど) で、他のサブ ビュー コントローラーを "含める" ように Containment を実装できるようになりました。

An example of View Controller Containment

子ビュー コントローラーには、親ビュー コントローラーに関連付けるメソッドとプロパティが含まれており、画面からのビューの表示と削除を操作できます。

macOS に組み込まれているすべてのコンテナー ビュー コントローラーには、独自のカスタム コンテナー ビュー コントローラーを作成する場合に従うことを Apple が提案する特定のレイアウトがあります。

The View Controller layout

コレクション ビュー コントローラーには、コレクション ビュー 項目の配列が含まれており、それぞれに独自のビューを含む 1 つ以上のビュー コントローラーが含まれています。

Segues

Segues は、アプリの UI を定義するすべてのシーン間のリレーションシップを提供します。 iOS のストーリーボードの作業に慣れている場合は、通常、iOS 用 Segues が全画面表示ビュー間の切り替えを定義していることがわかります。 これは、Segues が通常 "Containment" を定義する場合の macOS とは異なります。ここで、1 つのシーンは親シーンの子です。

macOS では、ほとんどのアプリは、分割ビューやタブなどの UI 要素を使用して、同じウィンドウ内でビューをグループ化する傾向があります。 iOS とは異なり、物理的な表示領域が限られているため、画面のオンとオフを切り替える必要があります。

プレゼンテーション のセグエ

macOS の封じ込めの傾向を考えると、モーダル Windows、シート ビュー、ポップオーバーなど、Presentation Segues が使用される状況があります。 macOS には、次の組み込みのセグエ型が用意されています。

  • 表示 - セグエのターゲットを非モーダル ウィンドウとして表示します。 たとえば、この種類の Segue を使用して、アプリでドキュメント ウィンドウの別のインスタンスを表示します。
  • モーダル - Segue のターゲットをモーダル ウィンドウとして表示します。 たとえば、この種類の Segue を使用して、アプリの [基本設定] ウィンドウを表示します。
  • シート - 親ウィンドウにアタッチされたシートとして Segue のターゲットを表示します。 たとえば、この種類のセグエを使用して、シートの検索と置換を表示します。
  • Popover - ポップオーバー ウィンドウのように、セグエのターゲットを表示します。 たとえば、この Segue 型を使用して、ユーザーが UI 要素をクリックしたときにオプションを表示します。
  • カスタム - 開発者によって定義されたカスタム Segue 型を使用して、Segue のターゲットを表示します。 詳細については、以下 の「カスタム セグエの作成 」セクションを参照してください。

Presentation Segues を使用する場合は、プレゼンテーション用の親ビュー コントローラーのメソッドをオーバーライド PrepareForSegue して初期化と変数を設定し、表示されているビュー コントローラーにデータを提供できます。

トリガーされたセグエ

トリガーされた Segues を使用すると、名前付き Segues を (Interface Builder の Identifier プロパティを使用して) 指定し、ユーザーがボタンをクリックしたり、コード内でメソッドを PerformSegue 呼び出したりなどのイベントによってトリガーされるようにすることができます。

// Display the Scene defined by the given Segue ID
PerformSegue("MyNamedSegue", this);

Segue ID は、アプリの UI をレイアウトするときに Xcode のインターフェイス ビルダー内で定義されます。

Entering a Segue Name

Segue のソースとして機能するビュー コントローラーでは、メソッドをオーバーライド PrepareForSegue し、Segue が実行され、指定されたビュー コントローラーが表示される前に必要な初期化を行う必要があります。

public override void PrepareForSegue (NSStoryboardSegue segue, NSObject sender)
{
    base.PrepareForSegue (segue, sender);

    // Take action based on Segue ID
    switch (segue.Identifier) {
    case "MyNamedSegue":
        // Prepare for the segue to happen
        ...
        break;
    }
}

必要に応じて、メソッドを ShouldPerformSegue オーバーライドし、Segue が C# コードを使用して実際に実行されるかどうかを制御できます。 手動で表示されるビュー コントローラーの場合は、メソッドを DismissController 呼び出して、不要になったときに表示から削除します。

カスタム セグエの作成

アプリで、macOS で定義されている組み込み Segues によって提供されない Segue 型が必要になる場合があります。 この場合は、アプリの UI をレイアウトするときに Xcode のインターフェイス ビルダーで割り当てることができるカスタム セグエを作成できます。

たとえば、(新しいウィンドウでターゲット シーンを開く代わりに) ウィンドウ内の現在のビュー コントローラーを置き換える新しい Segue 型を作成するには、次のコードを使用できます。

using System;
using AppKit;
using Foundation;

namespace OnCardMac
{
    [Register("ReplaceViewSeque")]
    public class ReplaceViewSeque : NSStoryboardSegue
    {
        #region Constructors
        public ReplaceViewSeque() {

        }

        public ReplaceViewSeque (string identifier, NSObject sourceController, NSObject destinationController) : base(identifier,sourceController,destinationController) {

        }

        public ReplaceViewSeque (IntPtr handle) : base(handle) {
        }

        public ReplaceViewSeque (NSObjectFlag x) : base(x) {
        }
        #endregion

        #region Override Methods
        public override void Perform ()
        {
            // Cast the source and destination controllers
            var source = SourceController as NSViewController;
            var destination = DestinationController as NSViewController;

            // Swap the controllers
            source.View.Window.ContentViewController = destination;

            // Release memory
            source.RemoveFromParentViewController ();
        }
        #endregion

    }
        
}

ここでは、いくつかの点に注意してください。

  • この属性を使用して、 Register このクラスを /macOS に Objective-C公開しています。
  • メソッドをオーバーライドして Perform 、カスタム Segue のアクションを実際に実行しています。
  • ウィンドウの ContentViewController コントローラーは、Segue のターゲット (宛先) で定義されたコントローラーに置き換えます。
  • メソッドを使用してメモリを解放するために、元のビュー コントローラーを RemoveFromParentViewController 削除します。

Xcode の Interface Builder でこの新しい Segue 型を使用するには、まずアプリをコンパイルしてから Xcode に切り替え、2 つのシーン間に新しいセグエを追加する必要があります。 スタイルCustom に設定し、Segue クラスを (カスタム Segue クラスの名前) にReplaceViewSegue設定します。

Setting the Segue class

ウィンドウ コントローラー

ウィンドウ コントローラーには、macOS アプリで作成できるさまざまなウィンドウの種類が含まれており、制御されます。 ストーリーボードの場合、次の機能があります。

  1. コンテンツ ビュー コントローラーを提供する必要があります。 これは、子ウィンドウと同じコンテンツ ビュー コントローラーになります。
  2. この Storyboard プロパティには、ウィンドウ コントローラーが読み込まれたストーリーボードが含まれます。それ以外の null 場合はストーリーボードから読み込まれません。
  3. メソッドを DismissController 呼び出して、指定されたウィンドウを閉じてビューから削除できます。

ビュー コントローラーと同様に、ウィンドウ コントローラーは PerformSegue、メソッド PrepareForSegue とメソッドを ShouldPerformSegue 実装し、Segue 操作のソースとして使用できます。

ウィンドウ コントローラーは、macOS アプリの次の機能を担当します。

  • 特定のウィンドウを管理します。
  • ウィンドウのタイトル バーとツールバー (使用可能な場合) を管理します。
  • コンテンツ ビュー コントローラーを管理して、ウィンドウの内容を表示します。

ジェスチャ認識エンジン

macOS 用ジェスチャ認識エンジンは、iOS の対応するジェスチャとほぼ同じであり、開発者は簡単にジェスチャ (マウス ボタンのクリックなど) をアプリの UI 内の要素に追加できます。

ただし、iOS のジェスチャはアプリの設計 (2 本の指で画面をタップするなど) によって決まる場合、macOS のほとんどのジェスチャはハードウェアによって決まります。

Gesture Recognizers を使用すると、UI の項目にカスタム操作を追加するために必要なコードの量を大幅に減らすことができます。 ダブルクリックとシングルクリックの間で自動的に決定できるため、イベントをクリックしてドラッグするなどの操作が可能です。

ビュー コントローラーでイベントをオーバーライドする MouseDown 代わりに、Gesture Recognizer を使用してストーリーボードを操作するときにユーザー入力イベントを処理する必要があります。

macOS では、次のジェスチャ認識エンジンを使用できます。

  • NSClickGestureRecognizer - マウスダウンイベントとアップイベントを登録します。
  • NSPanGestureRecognizer - マウス ボタンを下に登録し、イベントをドラッグアンドリリースします。
  • NSPressGestureRecognizer - 特定の時間イベントに対してマウス ボタンを押したまま登録します。
  • NSMagnificationGestureRecognizer - トラックパッド ハードウェアから拡大イベントを登録します。
  • NSRotationGestureRecognizer - トラックパッド ハードウェアから回転イベントを登録します。

ストーリーボード参照の使用

ストーリーボード参照を使用すると、大規模で複雑なストーリーボードデザインを作成し、元のストーリーボードから参照される小さなストーリーボードに分割できるため、複雑さが解消され、結果として得られる個々のストーリーボードの設計と保守が容易になります。

さらに、ストーリーボード参照は、同じストーリーボード内の別のシーンまたは別のシーンの特定のシーンに アンカー を提供できます。

外部ストーリーボードの参照

外部ストーリーボードへの参照を追加するには、次の操作を行います。

  1. ソリューション エクスプローラーで、Project名を右クリックし、[AddNew>File..] を選択します。>Mac>ストーリーボード。 新しいストーリーボードの 名前 を入力し、[ 新規 ] ボタンをクリックします。

    Adding a new Storyboard

  2. ソリューション エクスプローラーで、新しいストーリーボード名をダブルクリックして、Xcode のインターフェイス ビルダーで編集するために開きます。

  3. 通常どおりに新しいストーリーボードのシーンのレイアウトを設計し、変更を保存します。

    Designing the interface

  4. インターフェイス ビルダーで参照を追加するストーリーボードに切り替えます。

  5. オブジェクト ライブラリからデザイン サーフェイスにストーリーボード参照をドラッグします。

    Selecting a Storyboard Reference in the Library

  6. 属性インスペクターで、上で作成したストーリーボードの名前を選択します。

    Configuring the reference

  7. 既存のシーンの UI ウィジェット (ボタンなど) を Control キーでクリックし、先ほど作成した ストーリーボード 参照 への新しいセグエを作成します。 ポップアップ メニューから [表示 ] を選択して、Segue を完了します。

    Setting the Segue type

  8. ストーリーボードへの変更を保存します。

  9. Visual Studio for Macに戻り、変更を同期します。

アプリが実行され、ユーザーが Segue を作成した UI 要素をクリックすると、ストーリーボード リファレンスで指定された外部ストーリーボードの初期ウィンドウ コントローラーが表示されます。

外部ストーリーボードで特定のシーンを参照する

(初期ウィンドウ コントローラーではなく) 外部ストーリーボードを特定のシーンに参照を追加するには、次の操作を行います。

  1. ソリューション エクスプローラーで、外部ストーリーボードをダブルクリックして Xcode のインターフェイス ビルダーで編集するために開きます。

  2. 新しいシーンを追加し、通常と同様にレイアウトをデザインします。

    Designing the layout in Xcode

  3. Identity Inspector で、新しいシーンのウィンドウ コントローラーのストーリーボード ID を入力します。

    Setting the Storyboard I D to AltScene under Identity.

  4. インターフェイス ビルダーで参照を追加するストーリーボードを開きます。

  5. オブジェクト ライブラリからデザイン サーフェイスにストーリーボード参照をドラッグします。

    Selecting a Storyboard Reference from the Library

  6. Identity Inspector でストーリーボードの名前と、上で作成したシーンの参照 ID (ストーリーボード ID) を選択します。

    Setting the Reference I D to AltScene under Storyboard Reference.

  7. 既存のシーンの UI ウィジェット (ボタンなど) を Control キーでクリックし、先ほど作成した ストーリーボード 参照 への新しいセグエを作成します。 ポップアップ メニューから [表示 ] を選択して、Segue を完了します。

    Setting the Segue Type

  8. ストーリーボードへの変更を保存します。

  9. Visual Studio for Macに戻り、変更を同期します。

アプリが実行され、ユーザーが Segue を作成した UI 要素をクリックすると、ストーリーボード リファレンスで指定された外部ストーリーボードから指定された ストーリーボード ID を 持つシーンが表示されます。

同じストーリーボード内の特定のシーンを参照する

特定のシーンに同じストーリーボードへの参照を追加するには、次の操作を行います。

  1. ソリューション エクスプローラーで、ストーリーボードをダブルクリックして編集用に開きます。

  2. 新しいシーンを追加し、通常と同様にレイアウトをデザインします。

    Editing the storyboard in Xcode

  3. Identity Inspector で、新しいシーンのウィンドウ コントローラーのストーリーボード ID を入力します。

    Setting the Storyboard I D to IntScene under Identity.

  4. ツールボックスからデザイン サーフェイスにストーリーボード参照をドラッグします。

    Selecting a Storyboard Reference from the Library

  5. 属性インスペクターで、上で作成したシーンの参照 ID (ストーリーボード ID) を選択します。

    Setting the Reference I D to IntScene under Storyboard Reference.

  6. 既存のシーンの UI ウィジェット (ボタンなど) を Control キーでクリックし、先ほど作成した ストーリーボード 参照 への新しいセグエを作成します。 ポップアップ メニューから [表示 ] を選択して、Segue を完了します。

    Selecting the Segue Type

  7. ストーリーボードへの変更を保存します。

  8. Visual Studio for Macに戻り、変更を同期します。

アプリが実行され、ユーザーが Segue を作成した UI 要素をクリックすると、ストーリーボード リファレンスで指定されたのと同じ ストーリーボード ID のシーンが表示されます。

複雑なストーリーボードの例

Xamarin.Mac アプリでストーリーボードを操作する複雑な例については、 SourceWriter サンプル アプリを参照してください。 SourceWriter は、コードの完了とシンプルな構文の強調表示をサポートするシンプルなソース コード エディターです。

SourceWriter コード全体に詳細なコメントが付いていて、可能な場合は、重要な技術やメソッド、Xamarin.Mac ガイド ドキュメントの関連情報へのリンクが示されます。