Xamarin逆引きTips

Xamarin逆引きTips

Xamarin.iOSでStoryboardとXamarin.Formsを併用するには?

2014年6月11日

Storyboardで作成したiOSアプリの一部の画面に、Xamarin.Formsを利用する方法を解説する。

奥山 裕紳(@amay077
  • このエントリーをはてなブックマークに追加

 iOSアプリ開発では、画面のレイアウトおよび画面遷移はStoryboardに任せてしまうことが多い。いきなりXamarin.Formsへ全面的に移行するのは大変なので、一部の画面にXamarin.Formsを利用するのが実用的だろう。今回はその方法を解説する。

シナリオ

 下の図のようなStoryboardを利用した画面1、画面2、画面3があり、画面2にのみXamarin.Formsを適用する。

図1 シナリオ

1iOSアプリプロジェクトを作成する

 [iOS]-[iPhone]-[Single View Application]を作成する(図2)。プロジェクト名は「FormsInNativeViews.iOS」、ソリューション名は「FormsInNativeViews」とする。

図2 プロジェクト作成画面

 以下の手順で画面1~3をレイアウトする(図3)。

  • 作成されたFormsInNativeViews.iOSViewController.csファイルは使用しないので削除する。MainStoryboard.storyboardファイルをiOSデザイナーで開き、最初に表示されるViewControllerも使用しないので削除する
  • Toolboxから「Navigation Controller」と2つの「View Controller」を配置し、タイトル(Title)を(Navigation Controllerを飛ばして)左から「First」「Second」「Third」とする(なお、各ViewControllerは、下部のタイトル部分をクリックすると選択できる)
  • FirstにはToolboxからButtonコントロールを配置し、そのボタンをControlキーを押しながらSecondへドロップして[Push]形式(=画面遷移で利用する)のSegue(=セグエ。遷移を表現する線)を作成する。さらにSecondのViewController自身をControlキーを押しながらThirdへドロップしてPush形式のSegueを作成する。このSegueにはIdentifierにgoto_thirdを設定しておく
  • Thirdには、適当にLabelコントロールを配置しておく
図3 Storyboardでの画面デザイン

 Secondには、次の画面の右上の赤枠で示しているように、サブクラス「SecondViewController」を設定する。すると、SecondViewController.csファイルが作成される。

図4 SecondViewCotrollerの設定

2Xamarin.Formsプロジェクトを追加する

 ソリューションツリーの右クリックメニューから[追加]-[新しいプロジェクトを追加]と選択する(図5)。

図5 プロジェクト追加画面

 それにより表示されるダイアログで、[C#]-[Forms]-[Universal Xamarin.Forms Project (PCL)]を選択し、名前を「FormsInNativeViews」と入力して[OK]ボタンを押す(図6)。

図6 プロジェクト追加画面

 上記の操作により作成されたApp.csファイルは使用しないので削除する。代わりにMainPage.csファイルを作成し、以下のように実装する。

C#
using System;
using Xamarin.Forms;

namespace FormsInNativeViews
{
  public class MainPage : ContentPage
  {
    private readonly Button _button;

    public Button GotoThirdButton
    {
      get { return _button; }
    }

    public MainPage()
    {
      _button = new Button
      {
        Text = "Goto Third",
        Font = Font.SystemFontOfSize(30d),
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
      };

      this.Title = "Page by Xamarin.Forms";
      this.Content = _button;
      this.BackgroundColor = Color.Yellow;
    }
  }
}
StoryboardのSecondに表示させるXamarin.Formsによる画面の実装コード(MainPage.cs)

 これが、StoryboardのSecondに表示させるXamarin.Formsによる画面のコードだ。中央にボタンを1つ配置しただけの単純なものだ。そのボタンをクリックした時の処理をiOSプロジェクト側で実装できるように、GotoThirdButtonプロパティとして公開しておく。

3iOSプロジェクトにXamarin.Formsを利用するための設定を行う

 ソリューションツリーでFormsInNativeViews.iOSプロジェクト内の[参照]の右クリックメニューから[参照アセンブリの編集]を選択し、表示されるダイアログで[Projects]タブを選択。続いて[FormsInNativeViews]にチェックを入れて[OK]ボタンを押す(図7)。

図7 プロジェクト追加画面

 次に、メニューバーの[プロジェクト]-[Add Packages]を選択する。表示されるダイアログの右上の検索ボックスで「Xamarin.Forms」と入力して検索すると、同名のパッケージが見つかるのでチェックを入れて[Add Packages]を押す(図8)。

図8 パッケージ追加画面

 ソリューションツリーの「パッケージ」の中に「Xamarin.Forms」が追加されるはずだ。

4ViewControllerにXamarin.Formsの画面を適用する

 SecondViewController.csファイルを開き、下のように実装する。

C#
……省略……
using Xamarin.Forms;
using FormsInNativeViews;
……省略……

partial class SecondViewController : UIViewController
{
  public SecondViewController(IntPtr handle)
    : base(handle) { }

  public override void ViewDidLoad()
  {
    base.ViewDidLoad();

    Forms.Init(); // 初期化。実行時に一度だけ呼べばよい。

    var page = new MainPage();

    // ボタンクリック時に「goto_third」というIdentifierのSegueを実行する。
    page.GotoThirdButton.Clicked += (sender, e) => this.PerformSegue("goto_third", this);

    var viewController = page.CreateViewController();
    this.AddChildViewController(viewController);
    this.View.Add(viewController.View);
    viewController.DidMoveToParentViewController(this);
  }
}
Xamarin.Formsで作成したMainPage画面を、Secondに適用するコード(SecondViewController.cs)

 Secondを読み込んだ時に、Xamarin.Formsを初期化し、MainPageクラスのインスタンスを生成する。さらにCreateViewController()メソッドでViewControllerを生成して、それをSecondViewControllerの子Viewとして追加することで(=AddChildViewControllerメソッド~DidMoveToParentViewControllerメソッド)、Xamarin.Formsの画面をコンテンツとして表示させている。

 コードの書き順と説明が前後するが、MainPage画面のボタンを押した時に、Thirdの画面へ遷移するには、MainPageクラスでプロパティとして公開しておいたGotoThirdButtonを使い、Clickedイベントハンドラーにネイティブの画面遷移の実装(=PerformSegueメソッド)を書いている。

5実行する

 作成したプロジェクトを実行すると、図9のようになる。

図9 実行画面

【コラム】iOS7 の「潜り込み」

 実行画面の画面2(図9の中央)を見ると、Xamarin.Formsで定義した黄色い画面が、タイトルバー(UINavigationBar)の裏に潜り込んでいることが分かる。これはiOSの特有のものなので、他のプラットフォームと共通な画面にするときには注意が必要だ。この「潜り込み」は、ViewControllerの設定で回避することもできるが、それが「iOSらしい画面」かどうかは、検討が必要だろう。

まとめ

 Xamarin.Formsの画面(Page)をStoryboardと共存させる方法、および、Xamarin.Forms内のUIパーツのイベントで、ネイティブの処理を行う方法を解説した。Storyboardを使っていない場合は、PageからCreateViewControllerしたViewControllerを、NavigationController.PushViewControllerに指定して画面遷移させることもできる。

 GitHubのxamarin-forms-samplesリポジトリには、ネイティブとXamarin.Formsの相互利用の例として「Native2Forms」「Forms2Native」が用意されているので、これらも参考にしてほしい。

 今回Xamarin.Formsで作成した画面は、当然Xamarin.Androidでも利用可能だ。次回は、Xamarin.Androidのネイティブな画面にXamarin.Formsを利用する方法を解説する予定だ。

※以下では、本稿の前後を合わせて5回分(第4回~第8回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

4. Xamarin.Androidで画面遷移を行うには?

Xamarin.Androidで画面を追加する方法と、2つの画面間を遷移し、遷移先にデータを渡す方法、遷移先から返り値を得る方法を解説する。

5. iOS/Androidの画面レイアウトを共通化するには?(Xamarin.Forms)

Xamarin 3がリリースされた。その新機能として注目されるXamarin.Formsの概要と、基本的な使い方、メリット/デメリットを解説する。Xamarin.Formsを使ってiOS/Android/Windows Phone間で画面レイアウトも共通化しよう。

6. 【現在、表示中】≫ Xamarin.iOSでStoryboardとXamarin.Formsを併用するには?

Storyboardで作成したiOSアプリの一部の画面に、Xamarin.Formsを利用する方法を解説する。

7. Xamarin.AndroidでActivityとXamarin.Formsを併用するには?

iOSの場合と同じように、Androidアプリの一部の画面に、Xamarin.Formsを利用する方法を解説する。また、iOSとの挙動の違いやフラグメントとの併用についても言及する。

8. Xamarin.Formsからプラットフォーム固有の機能を利用するには?(DependencyService利用)

UIを共通化するフレームワーク「Xamarin.Forms」で、「DependencyService」機能を使用してiOS/Androidの各プラットフォーム固有の機能を実装する方法を解説する。

サイトからのお知らせ

Twitterでつぶやこう!


Build Insider賛同企業・団体

Build Insiderは、以下の企業・団体の支援を受けて活動しています(募集概要)。

ゴールドレベル

  • 日本マイクロソフト株式会社
  • グレープシティ株式会社