Bug 19180 - Incorrect orientation is reported by UIViewController InterfaceOrientation property
Summary: Incorrect orientation is reported by UIViewController InterfaceOrientation pr...
Status: RESOLVED NOT_REPRODUCIBLE
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 7.2.0
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-04-20 20:10 UTC by RichardH
Modified: 2017-07-24 18:49 UTC (History)
3 users (show)

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


Attachments
Test code to reproduce issue (15.69 KB, application/octet-stream)
2014-04-22 09:20 UTC, RichardH
Details


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 NOT_REPRODUCIBLE

Description RichardH 2014-04-20 20:10:17 UTC
I often use InterfaceOrientation.ToString() to get the current device orientation.  It is possible to create a scenario where:

InterfaceOrientation.ToString() reports the wrong orientation, and 

UIApplication.SharedApplication.StatusBarOrientation.ToString() reports the correct orientation.


Background: recently I was investigating how to force the correct orientation when popping a View Controller from the stack.  I had a VC presenting a landscape view and I wanted the previous VC to present a portrait view when it was popped.  A popular stack overflow answer to this problem is to (just before popping) quickly present and instantly dismiss a modal View Controller which forces the current View Controller to call UIInterfaceOrientationMask GetSupportedInterfaceOrientations() - a boolean can then be tested to switch the supported interface orientation back to portrait just as it is popped, meaning the next VC in the stack presents as portrait.

I implemented this as follows:

    public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
        {
            if (dismissing == false)
            {
                return UIInterfaceOrientationMask.All;
            }
            else
            {
                return UIInterfaceOrientationMask.Portrait | UIInterfaceOrientationMask.PortraitUpsideDown;
            }
        }



And the popping code:



    ForceOrientationViewController forceViewController = new ForceOrientationViewController();
                PresentViewController(forceViewController, false, ()=> { forceViewController.DismissViewController(false, null); });
                NavigationController.NavigationBarHidden = false;
                NavigationController.PopViewControllerAnimated(false);


ForceOrientationViewController is just a blank default template ViewController.  I subclassed it to see whether setting the View to UIColor.Clear and other things would make the process visually cleaner, but it essentially does nothing.


After popping, the previous VC being returned to does indeed display in portrait.  However, if a new VC is then pushed (e.g. via a UIButton tap) it doesn't have its InterfaceOrientation property set correctly.  It still retains the old landscape orientation value of the earlier popped VC.

So, for example:

InterfaceOrientation.ToString() may report "LandscapeLeft"

while

UIApplication.SharedApplication.StatusBarOrientation.ToString() reports "Portrait" (which is correct).
Comment 1 Sebastien Pouliot 2014-04-22 08:11:08 UTC
That should not be. OTOH what montouch.dll does it simply give you back the value from iOS (i.e. there's no caching or computation to determine the current value done inside Xamarin.iOS).

> It is possible to create a scenario where:

Can you attach such a (complete, self-contained) test case ? we can have a look, there might be something wrong (but at least we could confirm it's coming, or not, from iOS itself).
Comment 2 RichardH 2014-04-22 09:20:11 UTC
Created attachment 6629 [details]
Test code to reproduce issue

Here is some brief test code to reproduce the issue originally mentioned in the first comment.

Steps to reproduce:

1. Build and run project.
2. Tap/Click "Push ViewController" button.  Second ViewController is pushed to stack and view appears.
3. Rotate the device/simulator so that view changes to landscape
4. Tap/Click "Pop ViewController" button
5. Modal ViewController is presented and immediately dismissed.  Second ViewController is popped.  1st ViewController is forced back to portrait.
6. Tap "Push ViewController" button a second time.
7. Second ViewController is again pushed onto the stack and its view appears.
8. Inspect console:

InterfaceOrientation: LandscapeLeft
UIApplication.SharedApplication.StatusBarOrientation: Portrait

Note discrepancy between the two reported orientations.

This method of forcing orientation after popping a ViewController is suggested in an old answer on Stack Overflow.  It may be that my implementation is faulty and contributing to the issue (I was just playing around with it to see if it worked).  That said, I don't know why this would cause a difference between the two orientation properties.
Comment 3 John Miller [MSFT] 2017-07-24 18:49:58 UTC
Thanks so much for taking the time to submit this report! I attempted to reproduce this issue based on the bug description with the latest Xamarin.iOS 10.12.0.14, and I was unable to hit the problem. If this issue is still occurring for you, please reopen this report and attach an updated project that reproduces the issue, ideally starting with a new template project and then adding just the code necessary to demonstrate the issue. Thanks!