Xamarin,iPhoneアプリにサイドメニューを組み込む


はじめに

Xamarin.iOS で iPhone アプリにサイドメニューを組み込もうとしたのですが、このハードルの高いこと高いこと。Xcode で Swift ならオープンソースのライブラリがたくさんあるようなのですけどね。

まあ、嘆いてもしかたないので、頑張って探してみたところ Xamarin-SideBarXamarin.SideMenu という2つのオープンソースのライブラリが見つかりました。

Xamarin-SideBar はサンプルを実装してみたのですが、いまひとつうまく動作しなかったのでここでは除外します。

Xamarin.SideMenu はちゃんと動作したのですが2年間メンテナンスがされていないので、リポジトリをフォークするなどバックアップを取っておき、いざという場合は自分でメンテナンスをする覚悟で採用する必要がありますね。

この記事では、Xamarin.SideMenu の非常にシンプルなサンプルを提示します。大元のサンプルはほとんどサンプルになっていないので(実際に使うことを想定したサンプルではない)。

なお、開発環境は Visual Studio for Mac になります。

ゴールイメージ

ゴールイメージは、下図のようにサイドメニューが表示され画面遷移が行えることです。

f:id:fnyablog:20180908071302p:plain f:id:fnyablog:20180908071310p:plain f:id:fnyablog:20180908071315p:plain

サイドメニューの組み込み

ここからソースコードでサイドメニューをアプリに組み込んでいきます。

AppDelegate.cs ファイルに Window の制御を組み込みます。ナビゲーションのカスタマイズなどはここでおこないます。

using Foundation;
using UIKit;

namespace Xamarin.SideMenu.SimpleSample
{
    [Register("AppDelegate")]
    public class AppDelegate : UIApplicationDelegate
    {
        // class-level declarations

        public override UIWindow Window
        {
            get;
            set;
        }

        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            // create a new window instance based on the screen size
            Window = new UIWindow(UIScreen.MainScreen.Bounds);

            var spacePurple = UIColor.FromRGB(64, 0, 128);//Windowのカラー変更

            UIView.Appearance.TintColor = UIColor.White;//ナビゲーションのテキストカラー変更
            UISlider.Appearance.ThumbTintColor = spacePurple;
            UISwitch.Appearance.TintColor = spacePurple;
            UISwitch.Appearance.OnTintColor = spacePurple;
            UINavigationBar.Appearance.BarTintColor = spacePurple;
            UINavigationBar.Appearance.TintColor = UIColor.White;

            var controller = new UIViewController();
            controller.View.BackgroundColor = UIColor.LightGray;
            controller.Title = "My Controller";

            var cvc = new SideMenuSample();

            var navController = new UINavigationController(cvc) { };
            navController.NavigationBar.BarStyle = UIBarStyle.Black;

            Window.RootViewController = navController;

            // make the window visible
            Window.MakeKeyAndVisible();

            return true;
        }

        public override void OnResignActivation(UIApplication application)
        {
        }

        public override void DidEnterBackground(UIApplication application)
        {
        }

        public override void WillEnterForeground(UIApplication application)
        {
        }

        public override void OnActivated(UIApplication application)
        {
        }

        public override void WillTerminate(UIApplication application)
        {
        }
    }
}

新規にSampleTableView.cs ファイルを作成し、以下のように記述します。主にテーブルビューの動作を記述になりますね。

using System;
using UIKit;
using Xamarin.SideMenu;

namespace Xamarin.SideMenu.SimpleSample
{
    public class SampleTableView : UITableViewController
    {
        public SampleTableView()
        {
        }

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

            this.TableView.RegisterClassForCellReuse(typeof(UITableViewVibrantCell), "VibrantCell");
        }

        public override nint RowsInSection(UITableView tableView, nint section)
        {
            return 3;
        }

        public override UITableViewCell GetCell(UITableView tableView, Foundation.NSIndexPath indexPath)
        {
            var cell = tableView.DequeueReusableCell("VibrantCell");

            cell.TextLabel.Text = "Index " + indexPath.Row;

            return cell;
        }

        public override void RowSelected(UITableView tableView, Foundation.NSIndexPath indexPath)
        {
            tableView.DeselectRow(indexPath, true);

            var rnd = new Random(Guid.NewGuid().GetHashCode());

            var vc = new UIViewController() { };
            vc.View.BackgroundColor = UIColor.FromRGB(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));

            this.ShowViewController(vc, this);
        }
    }
}

最後にSideMenuSample.cs ファイルを新規追加し、以下のように記述します。画面左側メニューを有効にしています。ちなみに、右側メニューもサポートしています。詳しくはXamarin.SideMenuのサンプルをご確認ください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIKit;
using System.Drawing;
using Xamarin.SideMenu;

namespace Xamarin.SideMenu.SimpleSample
{
    class SideMenuSample : UIViewController
    {
        SideMenuManager _sideMenuManager;

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

            this.NavigationItem.SetLeftBarButtonItem(
                 new UIBarButtonItem("Left Menu", UIBarButtonItemStyle.Plain, (sender, e) =>
                 {
                     PresentViewController(_sideMenuManager.LeftNavigationController, true, null);
                 }),
                false);

            _sideMenuManager = new SideMenuManager();

            _sideMenuManager.PresentMode = (SideMenuManager.MenuPresentMode)0;//Slide In

            View.BackgroundColor = UIColor.White;
            Title = "Side Menu";


            SetupSideMenu();

            SetDefaults();
        }

        void SetupSideMenu()
        {
            _sideMenuManager.LeftNavigationController = new UISideMenuNavigationController(_sideMenuManager, new SampleTableView(), leftSide: true);

            _sideMenuManager.AddScreenEdgePanGesturesToPresent(toView: this.NavigationController?.View);

        }

        void SetDefaults()
        {
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }
    }
}

これで準備は整いました。

デバッグ実行してみると、Left Menuボタンが表示されています。これをクリックすると。

f:id:fnyablog:20180908071850p:plain

サイドメニューが左からみゅーんと出てきました。メニューをクリックすると。

f:id:fnyablog:20180908071933p:plain

ランダムな背景色のビューが表示されます。Side Menu で元に戻れるのもいいですね。

f:id:fnyablog:20180908072004p:plain

これにて無事に実装完了です!

なお、このソースコードは、GitHub に上げておいたので必要な場合はこちらもご確認ください。

https://github.com/fnya/Xamarin.SideMenu.SimpleSample

おわりに

ここまで調査が進むのに1週間もかかってしまいました。もともと Xamarin のサイドメニューに関する情報が少ない上に、特定のライブラリの使用方法は全くなかったですからね。仕方のないところでしょうか。

今回はサイドメニューでしたが、他のコントロールでも同じように苦しむのでしょうね。でも、C# で .NET Framework の機能を使える利点と比較するとうなってしまいます。

めげずに頑張りたいと思います。