我有一个iPhone应用程序,其中大部分都是纵向显示的,但是有一个视图控制器(视频播放器屏幕)必须支持纵向和横向两种方式(仅适用于iOS 8)。为了实现这一点,我已经将应用程序的plist设置为支持纵向和两种类型的横向,然后继承了UINavigationController
;在这个子类中,我重写了
- (BOOL)shouldAutorotate {
return YES;
}
and- (NSUInteger)supportedInterfaceOrientations {
if ([self.visibleViewController isKindOfClass:[MyVideoPlayerScreen class]]) {
return UIInterfaceOrientationMaskAllButUpsideDown;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
这个大体上按照预期工作:初始屏幕都是竖屏,即使设备旋转到横屏模式,仍然保持竖屏。视频播放器在最初展示时:
MyVideoPlayerScreen *newVC = [MyVideoPlayerScreen new];
[self.navigationController pushViewController:newVC animated:YES];
当设备是竖屏时,也会在设备转向为横屏时进行旋转 - 到目前为止一切顺利。
问题是,如果我将设备旋转到横屏,则视频播放器也会随之旋转,但是当我通过后退按钮关闭视频播放器屏幕时,底层视图控制器(它应该仅限于竖屏)现在也处于横屏状态。 如果我将设备旋转回竖屏,则视图控制器也会旋转回竖屏,并且从那时起正确地锁定为仅限竖屏。
如何使原始视图控制器(应仅限于竖屏)在弹出其上方的横屏视图控制器时自动返回到竖屏?
这个问题已经被问了无数次,但似乎发布的修复程序都是iOS 8中不再起作用的hack。
更新: 我发现了一个“准确”的解决方法,适用于iOS 8。 在我的 UINavigationController
子类中,我处理了<UINavigationControllerDelegate>
协议。 我实现了这个方法:
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (![viewController isKindOfClass:[MyVideoPlayerScreen class]]) {
// if the current orientation is not already portrait, we need this hack in order to set the root back to portrait
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation != UIInterfaceOrientationPortrait) {
// HACK: setting the root view controller to nil and back again "resets" the navigation bar to the correct orientation
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIViewController *vc = window.rootViewController;
window.rootViewController = nil;
window.rootViewController = vc;
}
}
}
这至少保留了我想要的UI状态。问题在于,当顶层视图控制器被解除并以动画方式移出屏幕时,底层视图控制器仍处于横向状态;然后突然跳转到纵向状态。虽然不理想,但总比没有好。
更新2: 我应该补充说明我是这样推送第二个视图控制器的:
ViewControllerPortraitLandscape *newVC = [ViewControllerPortraitLandscape new];
[self.navigationController pushViewController:newVC animated:YES];
更新3: 好的,这是完全可行的,适用于iOS 6及以上版本。修复甚至有点合理,尽管它工作的原因似乎没有出现在文档中。基本上,在需要在设备仍处于横向状态时将顶级视图控制器解除时需要重置为纵向的视图控制器中,只需要添加以下内容:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
尽管我的UINavigationController
子类完全负责旋转调用,但断点显示在顶层被解除之前,该基础视图控制器上的supportedInterfaceOrientations
会被调用,并且在导航控制器上一次性被调用。因此,我推断iOS会自己调用视图控制器本身以确定基础视图控制器应该处于什么方向(而不是询问导航控制器);如果没有显式地重写它,则会返回除了倒置之外的所有参数,因此iOS将其保留在横向模式下。
UINavigationController
,但是我的主导航控制器需要拥有这个方法,因为它只支持纵向。谢谢! - aramusss