Xamarin.iOS で特定の画面だけ向きを固定する時ハマったこと

画面A,B があって B だけ横向き固定にしたい。

これを Xamarin.iOS でやりたい。

Storyboard を Interface Builder で開いて、NavigationController のカスタムクラスを MyNavigationController とした。

viewcontroller orientaion lock in xamarin ios 01

すると、Xamarin Studio 側にも MyNavigationController.cs ができるので、Stackoverflow の通り、以下のように実装した。

//MyNavigationController.cs
// This file has been autogenerated from a class added in the UI designer.

using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Linq;

namespace MyApp
{
	public partial class MyNavigationController : UINavigationController
	{
		public MyNavigationController (IntPtr handle) : base (handle) { }

        public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
        {
            return this.ViewControllers.Last().PreferredInterfaceOrientationForPresentation();
        }

        public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
        {
            return this.ViewControllers.Last().GetSupportedInterfaceOrientations();
        }

        public override bool ShouldAutorotate()
        {
            return this.ViewControllers.Last().ShouldAutorotate();
        }

	}
}

次に、横固定にしたい画面Bを以下のように実装。

//BViewController.cs
// This file has been autogenerated from a class added in the UI designer.

using System;

using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace MyApp
{
	public partial class BViewController : UIViewController
	{
		public PhotoPreviewViewController (IntPtr handle) : base (handle)
		{
		}

        public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
        {
            return UIInterfaceOrientation.LandscapeLeft;
        }

        public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
        {
            return UIInterfaceOrientationMask.LandscapeLeft;
        }

        public override bool ShouldAutorotate()
        {
            return false;
        }
	}
}

これで動かしてみたものの、一向に画面が固定されない。 しばらく悩んだ後、MyNavigationController のコンストラクタにブレークポイントを仕掛けてデバッグしてみたとても止まらない。 よくよくアプリケーション出力のコンソールを見てみると、

Unknown class MyNavigationController in InterfaceBuilder file."

と出力されていることに気づいた。 なんか、.storyboard と C# クラスの関連付けがうまくいってないらしい。

ソリューションをクリアして、再ビルドしたらこのエラーは消え、画面Bの向きが固定されるようになった!

(ただ、縦画面のまま画面Bに遷移すると縦画面で固定されてしまう。これは実装が何か足りない気がする。)