6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[初心者さん・学生さん大歓迎!] Xamarin その1Advent Calendar 2017

Day 16

Xamarin.Forms for MacがStoryboardと仲良くする方法

Last updated at Posted at 2017-12-15

この記事は [初心者さん・学生さん大歓迎!] Xamarin その1 Advent Calendar 2017 の16日目の記事です。

題について

勢いでサクッとつけてしまった題ですが、思ってたのとちょっと違うところです。
実際には、「 他プラットフォームとの互換性を最大限に維持しつつ Xamarin.Forms for MacがStoryboardと仲良くする方法」ですね。

もっと標準コンロールで

Storyboardでは

101.png

こういうコントロールを出すのは楽なのに。
(もちろん、こいつだとsegue一発なんでXamarin.Formsでもコード書きゃ終いですが)
でもDataBindingやら他機種へのポーティングを考えるとXamarin.Formsのコード使えたら楽なのに。

というわけで、いいとこ取りする簡単な方法です。

実現方法

理屈:Xamarin.Forms

Xamarin.Forms for Macの動きとして。

  • Forms.Init()は適当な時に呼び出しても良い
  • Forms.Init()はFormsApplicationDelegate.LoadApplicationの前に呼びださなければいけない
  • ApplicationのMainPageは設定されていなくても良い
  • ApplicationのMainPageが設定されていなければ、FormsApplicationDelegate.Windowは設定されていなくても良い
  • FormsApplicationDelegate.LoadApplicationは最初のPage操作の前に呼び出されていなければいけない
  • Xamarin.FormsのPageからNSViewControllerを作れる

理屈:Storyboard

また、Storyboard起動からの呼び出し順は、

  1. FormsApplicationDelegate.<<constructor>>
  2. NSViewController.ViewDidLoad
  3. FormsApplicationDelegate.DidFinishLaunching

です。

理屈:統合

なので、本来ならFormsApplicationDelegate.DidFinishLaunchingでXamarin.Formsの処理を行いますが、その流れを変えて。

  1. アプリ起動、UI始動までStoryboardで行う
  2. Forms.Init()とLoadApplicationはFormsApplicationDelegate.<<constructor>>で行う
  3. Application.MainPageを設定しない
  4. FormsApplicationDelegate.Windowも設定しない
  5. 表示関連はPageで用意しておき、ViewControllerにくっつける
  6. くっつけるのはNSViewController.ViewDidLoadで行う
  7. データの保持、更新処理はXamarinのBindingObjectに納める
  8. BindingObjectからのデータ更新はPage側で受け、表示する

という処理にします。

作ってみた

Githubに作ったものを置いてみました1

[AppDelegate] (https://github.com/yakumo/XamarinHelloWorldTest/blob/master/src/mac/HelloWorldTest/AppDelegate.cs) : Storyboard

何もしないXamarin.Forms.Applicationのサブクラス(App)を作り、それをLoadApplicationで設定しています。
これで、StoryboardのDelegateとして読み込まれ、Xamarin.Forms的には初期化を行い、WindowはStoryboardのものを使うように設定しています。

他プラットフォームでは、LoadApplicationで設定しているのはHelloWorldAppです。

MainData : Xamarin.Forms

埋め込みリソースとして登録してあるJSONを読み込み、本棚データとして保持します2

TitlesViewController : Storyboard

StoryboardでメインウインドウのViewControllerとして設定されます。
ViewDidLoadでTitleListPageを子ViewControllerとして設定しています。

TitleListPage : Xamarin.Forms

MainDataをBindingContextとしてわりつけ、表示している本棚の中の本の一覧を表示します。
他プラットフォームだと、MasterDetailPageのDetailにわりつけてメインのページになっています。

BookshelvesViewController : Storyboard

ウインドウにわりつけられたToolBarのボタンからPopupする本棚の一覧を表示するViewControllerです。
ボタン押下でPopupまではStoryboardで設定されています。
ViewDidLoadでBookshelfListPageを子ViewControllerとして設定しています。

BookshelfListPage : Xamarin.Forms

MainDataをBindingContextとしてわりつけ、本棚一覧を表示します。
ポップアップの中身です。
他プラットフォームだと、MasterDetailPageのMasterにわりつけてます。

結論

意外に簡単にStoryboardと統合できました。
このやり方は、 Page.CreateViewController におんぶにだっこしてもらって実現できています3
MVVMで分けるのは微妙ではありますが、入力する量も少なくていいところではないかと思います。

  1. アイコンはICOOON MONOさんのものを使用しています。

  2. 作った後に気づきましたが、コンストラクタはprivateの方が良いですねぃ。

  3. iOSでの同じやり方は意外に難しそうです。ListViewェ…。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?