Bug 7361 - AutoRotation not working in iOS 6
Summary: AutoRotation not working in iOS 6
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 6.0.x
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Mike Bluestein
URL:
Depends on:
Blocks:
 
Reported: 2012-09-20 16:53 UTC by JohanO
Modified: 2012-09-20 21:38 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description JohanO 2012-09-20 16:53:14 UTC
Hi Guys,


I cannot for the life of me understand what is happening with Rotation. My views goes all screwy when it previously worked quite well. I guess I need to understand what changed in regards to rotation in MT 6?
Comment 1 Sebastien Pouliot 2012-09-20 20:32:04 UTC
Apple did introduce new things - but existing code should still behave like before (i.e. that you don't implement should not affect you).

Could you explain the situation in more details ? or better attach a test case that shows it ?
Comment 2 JohanO 2012-09-20 20:44:09 UTC
Hi Sebastien,

Testcase is difficult unless I upload my entire project. Basically I tried it like it was before but compiled it for iOS 6 and the views shift themselves around when I go into horizontal. I have one common base class and I try to set the layout properties of my iPad Xibs so that they just autoresize except for the odd image that needs to change into a longer one when changing to landscape. Because I had tremendous issues before iOS 5 with events not bubbling up, I did build my own little "ChildViewController" event bubbling mechanism. I have now replaced all of the code with the standard "AddChildViewController" code and overriden everything according to Apple docs and now rotation simply does not work in the simulator and on the device it goes haywire.

Here is the rotation related overrides in my base view controller. Maybe you can spot something obvious?

#region Built-In Auto-Rotation

		#region ShouldAutorotate
		/// <summary>
		///   Occurs when the user interface rotates.
		/// </summary>
		/// <param name="toInterfaceOrientation">
		/// A <see cref="UIInterfaceOrientation"/>
		/// </param>
		/// <returns>
		/// A <see cref="System.Boolean"/>
		/// </returns>
		public override bool ShouldAutorotate()
		{
			// BUG???? https://bugzilla.xamarin.com/show_bug.cgi?id=7361
			return true;
		}
		#endregion

		#region ShouldAutorotateToInterfaceOrientation
		/// <summary>
		/// Shoulds the autorotate to interface orientation.
		/// </summary>
		/// <returns>
		/// <c>true</c>, if autorotate to interface orientation was shoulded, <c>false</c> otherwise.
		/// </returns>
		/// <param name='toInterfaceOrientation'>
		/// To interface orientation.
		/// </param>
		[Obsolete]
		public sealed override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)
		{
			// BUG???? https://bugzilla.xamarin.com/show_bug.cgi?id=7361
			return true;
		}
		#endregion

		#region ShouldAutomaticallyForwardRotationMethods
		/// <summary>
		/// Gets a value indicating whether this <see cref="JustEnough.IPad.ViewControllerBase"/> should automatically forward
		/// rotation methods.
		/// </summary>
		/// <value>
		/// <c>true</c> if should automatically forward rotation methods; otherwise, <c>false</c>.
		/// </value>
		public sealed override bool ShouldAutomaticallyForwardRotationMethods
		{
			get
			{
				return true;
			}
		}
		#endregion

		#region ShouldAutomaticallyForwardAppearanceMethods
		/// <summary>
		/// Gets a value indicating whether this <see cref="JustEnough.IPad.ViewControllerBase"/> should automatically forward
		/// appearance methods.
		/// </summary>
		/// <value>
		/// <c>true</c> if should automatically forward appearance methods; otherwise, <c>false</c>.
		/// </value>
		public sealed override bool ShouldAutomaticallyForwardAppearanceMethods
		{
			get
			{
				return true;
			}
		}
		#endregion

		#region GetSupportedInterfaceOrientations 
		/// <Docs>
		/// To be added.
		/// </Docs>
		/// <remarks>
		/// To be added.
		/// </remarks>
		/// <summary>
		/// Gets the supported interface orientations.
		/// </summary>
		/// <returns>
		/// The supported interface orientations.
		/// </returns>
		public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
		{
			return UIInterfaceOrientationMask.All;
		}
		#endregion

		#region PreferredInterfaceOrientationForPresentation
		/// <Docs>
		/// To be added.
		/// </Docs>
		/// <remarks>
		/// To be added.
		/// </remarks>
		/// <summary>
		/// Preferreds the interface orientation for presentation.
		/// </summary>
		/// <returns>
		/// The interface orientation for presentation.
		/// </returns>
		public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
		{
			return UIInterfaceOrientation.Portrait;
		}
		#endregion
		
		#region WillRotate
		/// <summary>
		///   Occurs before the view controller is going to rotate.
		/// </summary>
		/// <param name="toInterfaceOrientation">
		/// A <see cref="UIInterfaceOrientation"/>
		/// </param>
		/// <param name="duration">
		/// A <see cref="System.Double"/>
		/// </param>
		public sealed override void WillRotate (UIInterfaceOrientation toInterfaceOrientation, double duration)
		{
			try
			{
				Debug.WriteLine(string.Format("WillRotate (To: {0}) - {1}", toInterfaceOrientation, GetType().Name));
				OnRotate(toInterfaceOrientation);
				/* iOS 5+ automaticallly forwards these events!

				if (_subViewControllers != null)
				{	
					foreach(UIViewController controller in _subViewControllers)
					{
						
						if (!(controller is ISupportAutoRotation))
							continue;
						
						controller.WillRotate(toInterfaceOrientation, duration);
					}
				}*/
				base.WillRotate (toInterfaceOrientation, duration);
			}
			catch(Exception ex)
			{
				HandleException(ex);
			}
		}
		#endregion
		
		#region DidRotate
		/// <summary>
		///   Occurs when the user interface has rotated.
		/// </summary>
		/// <param name="fromInterfaceOrientation">
		/// A <see cref="UIInterfaceOrientation"/>
		/// </param>
		public sealed override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
		{
			try
			{
				Debug.WriteLine(string.Format("DidRotate (from: {0}, to: {1}) - {2}", 
				                              fromInterfaceOrientation, 
				                              InterfaceOrientation, 
				                              GetType().Name));
				
				OnRotationComplete(this.InterfaceOrientation);

				/* iOS 5+ automaticallly forwards these events!
				if (_subViewControllers != null)
				{	
					foreach(UIViewController controller in _subViewControllers)
					{
						
						if (!(controller is ISupportAutoRotation))
							continue;
						
						controller.DidRotate(fromInterfaceOrientation);
					}
				}*/
				AdjustTabletView();
				base.DidRotate(fromInterfaceOrientation);
			}
			catch(Exception ex)
			{
				HandleException(ex);
			}
		}
		#endregion
			
		#region DidAnimateFirstHalfOfRotation
		/// <summary>
		///   Occurs when the first half of a rotation is animated.
		/// </summary>
		/// <param name="toInterfaceOrientation">
		/// A <see cref="UIInterfaceOrientation"/>
		/// </param>
		public override void DidAnimateFirstHalfOfRotation (UIInterfaceOrientation toInterfaceOrientation)
		{

			/* iOS 5+ automaticallly forwards these events!
			if (_subViewControllers != null)
			{	
				foreach(UIViewController controller in _subViewControllers)
				{
					
					if (!(controller is ISupportAutoRotation))
						continue;
					
					controller.DidAnimateFirstHalfOfRotation(toInterfaceOrientation);
				}
			}
			*/
			base.DidAnimateFirstHalfOfRotation (toInterfaceOrientation);
		}
		#endregion
		
		#region WillAnimateFirstHalfOfRotation
		/// <summary>
		///   Occurs before animating the first half of a rotation.
		/// </summary>
		/// <param name="toInterfaceOrientation">
		/// A <see cref="UIInterfaceOrientation"/>
		/// </param>
		/// <param name="duration">
		/// A <see cref="System.Double"/>
		/// </param>
		public override void WillAnimateFirstHalfOfRotation (UIInterfaceOrientation toInterfaceOrientation, double duration)
		{
			/* iOS 5+ automaticallly forwards these events!
			if (_subViewControllers != null)
			{	
				foreach(UIViewController controller in _subViewControllers)
				{
					
					if (!(controller is ISupportAutoRotation))
						continue;
					
					controller.WillAnimateFirstHalfOfRotation(toInterfaceOrientation, duration);
				}
			}*/
			base.WillAnimateFirstHalfOfRotation (toInterfaceOrientation, duration);
		}
		#endregion
		
		#region WillAnimateRotation
		/// <summary>
		///   Occurs when the view controller will animate the interface rotation.
		/// </summary>
		/// <param name="toInterfaceOrientation">
		/// A <see cref="UIInterfaceOrientation"/>
		/// </param>
		/// <param name="duration">
		/// A <see cref="System.Double"/>
		/// </param>
		public override void WillAnimateRotation (UIInterfaceOrientation toInterfaceOrientation, double duration)
		{
			/* iOS 5+ automaticallly forwards these events!
			if (_subViewControllers != null)
			{	
				foreach(UIViewController controller in _subViewControllers)
				{
					
					if (!(controller is ISupportAutoRotation))
						continue;
					
					controller.WillAnimateRotation(toInterfaceOrientation, duration);
				}
			}
			*/
			base.WillAnimateRotation (toInterfaceOrientation, duration);
		}
		#endregion
		
		#region WillAnimateSecondHalfOfRotation
		/// <summary>
		///  Occurs when the second half of the rotation is animated.
		/// </summary>
		/// <param name="fromInterfaceOrientation">
		/// A <see cref="UIInterfaceOrientation"/>
		/// </param>
		/// <param name="duration">
		/// A <see cref="System.Double"/>
		/// </param>
		public override void WillAnimateSecondHalfOfRotation (UIInterfaceOrientation fromInterfaceOrientation, double duration)
		{
			/* iOS 5+ automaticallly forwards these events!
			if (_subViewControllers != null)
			{	
				foreach(UIViewController controller in _subViewControllers)
				{
					
					if (!(controller is ISupportAutoRotation))
						continue;
					
					controller.WillAnimateSecondHalfOfRotation(fromInterfaceOrientation, duration);
				}
			}*/
			base.WillAnimateSecondHalfOfRotation (fromInterfaceOrientation, duration);
		}
		#endregion
		
		#endregion
Comment 3 JohanO 2012-09-20 21:17:48 UTC
Hi Sebastien,

I found it. It might be a good idea to let people know. Because my project exists from iOS 2 days i have not changed the main program logic and application delegate code for ages.

You have to set the main windows root view controller property in order for the rotation events to work.

Available in iOS 4.0 and later.
MainWindow.RootViewController = myController;
Comment 4 Sebastien Pouliot 2012-09-20 21:24:27 UTC
Johan, a huge thanks for the tip! It would have been pretty difficult to find out.

c.c. Bryan (doc) and Chris (support)
Comment 5 bryan costanich 2012-09-20 21:38:53 UTC
Hm. good to know. I think we've updated most of our samples to use Root, but we should make sure they get updated, and also add this not to our intro doc. 

assigning to MikeB so it makes it into the intro doc.