我有一个iPhone应用程序,其中大多数都是纯纵向的,但具有一个必须同时支持纵向和横向的视图控制器(视频播放器屏幕)(仅适用于iOS 8)。为此,我将应用程序的plist设置为支持人像和两种风景,然后将其子类化UINavigationController
;在这个子类中,我重写
- (BOOL)shouldAutorotate {
return YES;
}
和
- (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中不再起作用的黑客。
更新:我已经找到了适用于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进行的,以确定底层视图控制器应处于哪个方向(并且它不会为此请求导航控制器);如果未明确覆盖它,它将返回all-but-upside-down参数,因此iOS会将其保留在横向位置。
事实证明,这是一个简单的解决方案:您可以通过UINavigationController
我在此处发布的子类来驱动整个过程(即,在视图控制器本身中不实现这些旋转方法中的任何一种),除了对于需要纵向显示的任何视图控制器而言,仅,您还需要实现以下功能:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
使用断点,您可以看到在撤消其上方的推入视图控制器之前调用了此方法。iOS大概使用此调用来确定“显示的”视图控制器应处于哪个方向(取消顶级视图控制器后,将调用对导航控制器子类的同一调用)。
通过在视图控制器中实现此方法,一切都会按预期进行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句