在iOS6设备上使用标签栏控制器忽略了ShouldAutorotateToInterfaceOrientation

时间:2013-02-21 10:44:03

标签: ios6 xamarin.ios screen-rotation

我有一个使用6.1 SDK的Monotouch 6.0.10 iPhone应用程序,但针对的是iOS 4.0及更高版本,我尝试使用ShouldAutorotateToInterfaceOrientation强制将其中一个视图强制为纵向方向。我现在已经不赞成使用,但仍然需要支持iOS4 / iOS5设备。

为了尝试隔离问题,我写了一个最小的测试应用程序。它没有XIB,并且有一个带有一个选项卡的UITabBarController。该选项卡有一个UINavigationController,UINavigationController有一个UIViewController(点击一个hello world按钮)。

在AppDelegate中我有:

tabController = new TabController();
window.RootViewController = tabController;

在UITabBarController和UINavigationController中我有:

public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)
    {
        return true;
    }

在UIViewController中我有:

public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)
{
    if ( toInterfaceOrientation == UIInterfaceOrientation.Portrait )
    {
        return true;
    }
    else
    {
        return false;
    }
}

嗯,至少在iOS 6.1设备上,那些似乎完全被忽略的那些ShouldAutorotateToInterfaceOrientation。那里的断点没有达到,如果我强迫它们在每种情况下都返回false,那么旋转仍然会发生。

我的理解是,ShouldAutomaticallyForwardRotationMethods默认为true,因此似乎无法提供解决方案。除了Glen Schmidt在此提出的建议之外,没有运气就梳理了论坛:iOS 6 rotations: supportedInterfaceOrientations doesn´t work?但遗憾的是我对如何将其翻译成MonoTouch感到迷失:

QUOTE

If you want to replicate the pre-iOS 6 behaviour where all the views in the navigation stack / tab bar have to agree on an allowable set of orientations, put this in your subclass of UITabBarController or UINavigationController:

- (NSUInteger)supportedInterfaceOrientations
{
    NSUInteger orientations = [super supportedInterfaceOrientations];

    for (UIViewController *controller in self.viewControllers)
        orientations = orientations & [controller supportedInterfaceOrientations];

    return orientations;
}

引文结束

我也理解我甚至不希望通过ShouldAutoRotate / SupportedInterfaceOrientations为我的iOS6用户解决它,因为这会导致iOS4 / IOS5轮换失败。

任何建议都非常感谢!

比尔。

1 个答案:

答案 0 :(得分:2)

找到一个有效的解决方案,经过相当多的抨击。有人可能会对此有所改进。

问题

我的应用程序基于SDK 6.1,面向iOS4,iOS5和iOS6设备。除了必须以纵向固定的屏幕外,它需要允许所有屏幕旋转。该应用程序有一个UITabBarController,大多数选项卡都有一个UINavigationController,下面有堆叠视图。

对于iOS4 / iOS5用户,关键是应用程序根视图控制器中不推荐使用的ShouldAutorotateToInterfaceOrientation()方法(在我的情况下为标签栏控制器)。此方法不会在任何其他视图控制器中自动调用,但当然根视图控制器可以在当前视图控制器中调用同名方法。

对于iOS6用户,关键是应用程序根视图控制器中的ShouldAutorotate()/ GetSupportedInterfaceOrientations()。同样,这些方法不会在任何其他视图控制器中自动调用,但根视图控制器可以在当前视图控制器中调用相同名称的方法。

对于我在原帖中描述的简单测试应用程序:

在AppDelegate / FinishedLaunching中:

window.RootViewController = tabController;

在AppDelegate中:

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations (UIApplication application, UIWindow forWindow)
{
    return UIInterfaceOrientationMask.All;
}

在TabController中:

public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)  // iOS4/iOS5 only
{
    try
    {
        UINavigationController navController = (UINavigationController)SelectedViewController;
        UIViewController targetController = navController.ViewControllers[0];
        if ( targetController.Title == "Greetings")
        {
            if ( toInterfaceOrientation == UIInterfaceOrientation.Portrait )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    catch
    {
        return true;
    }
    return true;
}

public override bool ShouldAutorotate() // iOS6+ only
{
    return true;
}

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()  // iOS6+ only
{
    try
    {
        UINavigationController navController = (UINavigationController)SelectedViewController;
        UIViewController targetController = navController.ViewControllers[0];
        return targetController.GetSupportedInterfaceOrientations();
    }
    catch
    {
        return UIInterfaceOrientationMask.All;
    }
    return UIInterfaceOrientationMask.All;
}

在需要为肖像的视图控制器中:

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()  // iOS6+ only
{
    return UIInterfaceOrientationMask.Portrait;
}

我的实际应用程序需要稍微复杂一点的东西,但是沿着相同的路线。例如,在tabbarcontroller中:

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
    try
    {
        UINavigationController navController = (UINavigationController)SelectedViewController;
        if ( navController.Title == "Tracking" )        // Are we on the Tracking tab?
        {
            // Yes. Looking for RedLaser's BarcodePickerController
            UIViewController targetController = navController.ViewControllers[1];       // BarcodePicker would be second on nav stack
            string controllerType = targetController.GetType().Name;

            if ( controllerType == "BarcodePickerController" )                          // Is this BarcodePicker?   
            {
                return UIInterfaceOrientationMask.Portrait;                             // Yes, force portrait orientation                          
            }
        }
        else
        {
            return UIInterfaceOrientationMask.All;                                      // No, allow any orientation
        }
    }
    catch
    {
        return UIInterfaceOrientationMask.All;                                          // Not BarcodePicker, allow any orientation
    }
    return UIInterfaceOrientationMask.All;
}