我有一个使用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轮换失败。
任何建议都非常感谢!
比尔。
答案 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;
}