Xamarin の watchOS テーブル コントロール

watchOS WKInterfaceTable コントロールは、対応する iOS コントロールよりもはるかにシンプルですが、同様の役割を果たします。 カスタム レイアウトを持ち、タッチ イベントに応答できる行のスクロール リストが作成されます。

Watch table listWatch table detail

テーブルの追加

[テーブル] コントロールをシーンにドラッグします。 既定では、次のようになります (単一の未指定の行レイアウトが表示されます)。

Adding a table

コードで参照できるように、[プロパティ] パッドの [名前] ボックスでテーブルに名前を付けます。

行コントローラーを追加する

テーブルには、既定で [グループ] コントロールを含む行コントローラーによって表される単一の行が自動的に含まれます。

行コントローラーの [クラス] を設定するには、[ドキュメント アウトライン] で行を選択し、[プロパティ] パッドにクラス名を入力します。

Entering a class name in the Properties pad

行のコントローラーのクラスが設定されると、IDE でプロジェクトに対応する C# ファイルが作成されます。 コントロール (ラベルなど) を行にドラッグし、コードで参照できるように名前を付けます。

行の作成と設定

SetNumberOfRows は、Identifier を使用して正しいものを選択する各行に対して行コントローラー クラスを作成します。 行コントローラーにカスタム Identifier を指定した場合は、以下のコード スニペットで既定値を使用した識別子に変更します。 SetNumberOfRows が呼び出されるとRowController行ごとに作成され、テーブルが表示されます。

myTable.SetNumberOfRows ((nint)rows.Count, "default");
    // loads row controller by identifier

重要

テーブル行は、iOS の場合と同様に仮想化されません。 行数を制限してみてください (Apple では 20 行未満をお勧めします)。

行が作成されたら、各セルを設定する必要があります (iOS では GetCell の場合と同様)。 WatchTables の例のこのコード スニペットは、各行のラベルを更新します

for (var i = 0; i < rows.Count; i++) {
    var elementRow = (RowController)myTable.GetRowController (i);
    elementRow.myRowLabel.SetText (rows [i]);
}

重要

SetNumberOfRows を使用してから GetRowController を使用してループ処理すると、テーブル全体がウォッチに送信されます。 後続のテーブルのビューで、特定の行を追加または削除する必要がある場合は、パフォーマンスを向上させるために InsertRowsAtRemoveRowsAt を使用します。

タップに応答する

行の選択に応答するには、次の 2 つの方法があります。

  • インターフェイス コントローラーに DidSelectRow メソッドを実装するか、
  • ストーリーボードにセグエを作成し、別のシーンを開くために行の選択が必要な場合は GetContextForSegue を実装します。

DidSelectRow

プログラムによって行の選択を処理するには、DidSelectRow メソッドを実装します。 新しいシーンを開くには、PushController を使用し、使用するシーンの識別子とデータ コンテキストを渡します。

public override void DidSelectRow (WKInterfaceTable table, nint rowIndex)
{
    var rowData = rows [(int)rowIndex];
    Console.WriteLine ("Row selected:" + rowData);
    // if selection should open a new scene
    PushController ("secondInterface", rows[(int)rowIndex]);
}

GetContextForSegue

ストーリーボード上のセグエを、テーブル行から別のシーンにドラッグします ([コントロール] キーを押しながらドラッグします)。 必ずセグエを選択し、[プロパティ] パッドに識別子を付与します (以下の例では secondLevel など)。

インターフェイス コントローラーで、GetContextForSegue メソッドを実装し、セグエによって提示されるシーンに提供する必要があるデータ コンテキストを返します。

public override NSObject GetContextForSegue (string segueIdentifier, WKInterfaceTable table, nint rowIndex)
{
    if (segueIdentifier == "secondLevel") {
        return new NSString (rows[(int)rowIndex]);
    }
    return null;
}

このデータは、Awake メソッドでターゲット ストーリーボード シーンに渡されます。

複数の行型

既定では、テーブル コントロールの設計できる行型は 1 つです。 行 'テンプレート' をさらに追加するには、[プロパティ] パッドの [行] ボックスを使用して、追加の行コントローラーを作成します。

Setting the number of Prototype rows

[行] プロパティを 3 に設定すると、コントロールをドラッグするための追加の行プレースホルダーが作成されます。 各行に対して、[プロパティ] パッドで [クラス] の名前を設定して、行コントローラー クラスが作成されるようにします。

The prototype rows in the designer

テーブルにさまざまな行型を設定するには、SetRowTypes メソッドを使用して、テーブルの各行に使用する行コントローラーの種類を指定します。 行の識別子を使用して、各行に使用する行コントローラーを指定します。

この配列の要素数は、テーブルにあると想定される行数と一致する必要があります。

myTable.SetRowTypes (new [] {"type1", "default", "default", "type2", "default"});

複数の行コントローラーを含むテーブルを設定する場合は、UI を設定するときに、想定される種類を把握しておく必要があります。

for (var i = 0; i < rows.Count; i++) {
    if (i == 0) {
        var elementRow = (Type1RowController)myTable.GetRowController (i);
        // populate UI controls
    } else if (i == 3) {
        var elementRow = (Type2RowController)myTable.GetRowController (i);
        // populate UI controls
    } else {
        var elementRow = (DefaultRowController)myTable.GetRowController (i);
        // populate UI controls
    }
}

垂直方向の詳細ページング

watchOS 3 では、テーブルの新機能として、テーブルに戻って別の行を選択しなくても、各行に関連する詳細ページをスクロールできる機能が導入されました。 詳細画面は、上下にスワイプするか、Digital Crown を使用してスクロールできます。

Vertical Detail Paging exampleVertical paging detail

重要

この機能は現在、Xcode Interface Builder でストーリーボードを編集することによってのみ使用できます。

この機能を有効にするには、デザイン サーフェスで WKInterfaceTable を選択し、[垂直方向の詳細ページング] オプションにチェックを入れます。

Selecting the Vertical Detail Paging option

Apple で説明されているように、テーブル ナビゲーションではページングを機能させるためにセグエを使用する必要があります。 PushController を使用している既存のコードを書き直して、代わりにセグエを使用するようにします。

付録: 行コントローラーのコード例

デザイナーで行コントローラーが作成されると、IDE で 2 つのコード ファイルが自動的に作成されます。 参考のために、これらの生成されたファイルのコードを以下に示します。

クラスに最初の名前が付けられます。たとえば RowController.cs は次のようになります。

using System;
using Foundation;

namespace WatchTablesExtension
{
    public partial class RowController : NSObject
    {
        public RowController ()
        {
        }
    }
}

もう 1 つの .designer.cs ファイルは、1 つの WKInterfaceLabel コントロールを持つ次の例のように、デザイナー画面で作成されるアウトレットとアクションを含む部分クラス定義です。

using Foundation;
using System;
using System.CodeDom.Compiler;
using UIKit;

namespace WatchTables.OnWatchExtension
{
    [Register ("RowController")]
    partial class RowController
    {
        [Outlet]
        [GeneratedCode ("iOS Designer", "1.0")]
        public WatchKit.WKInterfaceLabel MyLabel { get; set; }

        void ReleaseDesignerOutlets ()
        {
            if (MyLabel != null) {
                MyLabel.Dispose ();
                MyLabel = null;
            }
        }
    }
}

ここで宣言されているアウトレットとアクションはコードで参照できます。ただし、.designer.cs ファイルを直接編集することはできません。