Thursday, October 18, 2012

More orientation in iOS with MonoTouch

I ran into some interesting orientation distinctions with MonoTouch development. Luckily the good folks at Xamarin were very helpful on their forums.

 Regarding orientation, this is what I learned from Adam Kemp:

There are two kinds of orientation: device orientation UIDeviceOrientation and interface orientation UIInterfaceOrientation. Interface orientation tells you whether it's portrait, portrait upside down, landscape left, or landscape right. Device orientation has more spatial orientations like face up or face down (i.e., how is the user holding the device, rather than what does the screen look like). Device orientation is much more prone to changes even when the interface doesn't change at all (and sometimes the device doesn't know at all, hence the "unknown").

UIDevice.CurrentDevice.Orientation gives you the device orientation.

To get interface orientation you use UIApplication.SharedApplication.StatusBarOrientation.

You can also observe changes to the orientation by adding an observer like this:

   _interfaceNotificationHandle = 
         NSNotificationCenter.DefaultCenter.AddObserver(
            UIApplication.DidChangeStatusBarOrientationNotification, 
            HandleInterfaceOrientationDidChangeNotification); 


And don't forget to unregister (in this case I do it in Dispose(), but for a view you might want to register when the view is added to a window and unregister when it's removed):


public void Dispose() 
{ 
    if (!_disposed) 
    { 
        if (_interfaceNotificationHandle != null) 
        { 
            NSNotificationCenter.DefaultCenter
                .RemoveObserver(_interfaceNotificationHandle); 

            _interfaceNotificationHandle = null; 
        }
        
        _disposed = true; 
         
    } 
}

Wednesday, October 17, 2012

Change orientation automatically with iOS6 and MonoTouch

Orientation and auto rotation in iOS6 with MonoTouch is slightly less obvious then I had hoped. It took me a little while to get it right, so maybe this will help others. To get your app to auto-rotate you will need to make sure you have done the following:

  1. Edited your Info.plist to specify allowed orientations
  2. Make sure you have RootController assigned to your view. Without this auto rotation will not work and you will get a compile time warning - "Application windows are expected to have a root view controller at the end of application launch". 

Do the following in AppDeligate.cs

UIWindow window;

public override bool FinishedLaunching (UIApplication app, 
                                           NSDictionary options)
{
     window = new UIWindow (UIScreen.MainScreen.Bounds);
     
     // change this to your controller
     var cvc = new SomeViewController(); 
     window.RootViewController = cvc; 
   
     // make the window visible
     window.MakeKeyAndVisible ();

     return true;
}


Once you are done with this, you should get auto-rotation!

Next, you can specify allowed orientations (if you want to limit to a specific set) either in AppDeligate.cs (globally) or in your controller level using the following override:

public override UIInterfaceOrientationMask 
                  GetSupportedInterfaceOrientations 
                     (UIApplication application, UIWindow forWindow)
{
  return UIInterfaceOrientationMask.Landscape;
}
Also, on the controller level, you can disable auto rotation all together using the following:

public override bool ShouldAutorotate()
{
         return false;
}

Hope this helps! Leave me a comment if this worked for you.