SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.iOS ページビューコントローラ

【 Xamarin 記事一覧 】


1 ページの作成

f:id:furuya02:20140706171906p:plain:w150:left
まずは、ページコントローラで表示するための1つのページを作成します。
UIViewControllerを継承したもので、ビューの中央にページ数を表示しています。

ページ数は、コンストラクタで初期化し、プロパティ「Index」で取得できます。

//中央にページ数が表示されるだけのビュー(1ページ分)
sealed class OnePage : UIViewController {
    //ページ数
    public int Index {get;private set;}
    //コンストラクタ
    public OnePage(int index) {
        Index = index;//ページ数を保存
        View.BackgroundColor = UIColor.White;
        //ビューの中央にページ数のラベルを表示する
        var label = new UILabel {
            Bounds = new RectangleF(0, 0, 50, 30),
            Text = string.Format("- {0} -", index),
            Center = new PointF(View.Bounds.Width / 2, View.Bounds.Height / 2),
            TextAlignment = UITextAlignment.Center
        };
        //作成したラベルを追加
        Add(label);
    }
}

2 ページビューコントロールの生成と初期化

次に、アプリの起動時に表示されるビューとして、UIWindowのRootViewControllerにページビューコントローラを設定します。

ページコントローラのコンストラクタでは、次の4つまで初期化が可能です。

  • UIPageViewControllerTransitionStyle アニメーション方法 [PageCurl(めくり),Scroll(スクロール)]
  • UIPageViewControllerNavigationOrientation アニメーション方向 [Horizontal,Vertical]
  • UIPageViewControllerSpineLocation 綴じ位置 [Max(右開き),Min(左開き),Mid(中綴じ)]
  • float ページ間隔

続いて、SetViewControllersにより表示を初期化します。SetViewControllersのパラメータは次のとおりです。

  • UIViewControllers[] 最初に表示するビュー(中綴じの場合だけ2つ必要)
  • UIPageViewControllerNavigationDirection ページ指定の方向
  • bool エフェクトの有無
  • UICompletionHandler ページ遷移後の処理


[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate {
    UIWindow window;

    public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
        window = new UIWindow(UIScreen.MainScreen.Bounds);

        //ページビューコントローラの生成
        var pageViewController = new UIPageViewController(
            UIPageViewControllerTransitionStyle.PageCurl,
            UIPageViewControllerNavigationOrientation.Horizontal,
            UIPageViewControllerSpineLocation.Min, 20f) {
                DataSource = new MyDataSource()
            };

        //ページ数が1の最初のページを生成
        var onePage = new OnePage(1);
        //ページビューコントローラーの初期化
        pageViewController.SetViewControllers(
            new UIViewController[] { onePage }, //最初のページ
            UIPageViewControllerNavigationDirection.Forward,true,null);

        //windowのRootViewControllerにセットする
        window.RootViewController = pageViewController;
          

        window.MakeKeyAndVisible();
        return true;
    }
}

3 タッチ操作によるページ遷移

ページ遷移をタッチで操作するためには、プロパティDataSourceにUIPageViewControllerDataSource型のデリゲートクラスを指定する必要があります。

UIPageViewControllerDataSourceでは、GetPreviousViewController(前のページ)及びGetNextViewController(次のページ)のオーバーライドが必須であり、ここで、必要な次のページを生成します。

サンプルでは、現在ページ数を取得し、数を増減して新たなページを生成しています。また、このメソッドでnullを返すと、ページは遷移しなくなるため、1ページより前には行かないようになっています。


class MyDataSource : UIPageViewControllerDataSource {
    //前のページを返す
    public override UIViewController GetPreviousViewController(UIPageViewController pageViewController, UIViewController referenceViewController) {
        //表示中のページからページ数を取得する
        var index = ((OnePage)referenceViewController).Index;
        if (index > 1){ //ページ数が、1より多い時だけ処理する(0ページには遷移できない)
            //ページ数を1減してページを作成する
            return new OnePage(index - 1);
        }
        return null;
    }
    //次のページを返す
    public override UIViewController GetNextViewController(UIPageViewController pageViewController,
        UIViewController referenceViewController){
        //表示中のページからページ数を取得する
        var index = ((OnePage) referenceViewController).Index;
        //ページ数を1増してページを作成する
        return new OnePage(index + 1);
    }
}


4 イベントによるページ遷移

ボタン等でページを遷移させる場合は、先にページビューコントローラの初期化で使用したSetViewControllersを使用します。

この場合、毎回、妥当なビューで初期化することで、ページ遷移を実現します。


//次のページを表示するイベント
buttonNext.TouchUpInside+= (s, a) => {
    //現在のページを取得
    var index = ((OnePage) pageViewController.ViewControllers[0]).Index;

    //ページビューコントローラーの初期化
    pageViewController.SetViewControllers(
         new UIViewController[]{ new OnePage(index + 1) 
         }, UIPageViewControllerNavigationDirection.Forward, true, null);
};

【 Xamarin 記事一覧 】