![](/img/trans.png)
[英]UINavigationController: show embedded view controllers with different orientations after each transition?
[英]Restrict/Force only some view controllers to specific orientations when using UITabBarController and/or UINavigationController
我在网上搜寻了很多东西,但是找不到确切的答案。 当将一个UIViewController
嵌入到UINavigationController
本身是UITabBarController
一部分时,只有一种UIViewController
支持横向模式的最佳方法是什么?
像这样的大多数解决方案都建议覆盖
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
在AppDelegate
。 这在某种程度上是可行的,但是当从唯一一个支持横向模式的ViewController
返回时,所有其他(非横向ViewController)也将处于横向。 他们不保持纵向。
我见过应用程序能正确实现这一点,所以我知道一定有可能实现。 例如,电影播放器应用程序通常仅是纵向的,但是实际的电影播放器视图以强制横向模式模态显示。 解散模态视图控制器后,基础视图控制器仍正确以纵向放置,
有什么提示吗?
经过大量研究,这是我的结论:
首先,我尝试实施
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
如此处所述在 AppDelegate中运行,适用于大多数情况。 但是除了感到“ hacky”外,还有一个严重的陷阱:例如,当显示AVPlayerViewController
时,模式显示的视图控制器的变通方法(请参阅“模式控制器的小问题”一节)由于其实现了自己的关闭而失效方法,您无法将其设置为self.isPresented
(不幸的是, viewWillDisappear:
为时已晚)。
因此,我采用了为UITabBarController
和UINavigationController
使用子类的另一种方法,它感觉更干净,但也更加冗长:
#import <UIKit/UIKit.h>
@interface CustomNavigationController : UINavigationController
@end
#import "CustomNavigationController.h"
@implementation CustomNavigationController
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
@end
#import <UIKit/UIKit.h>
@interface CustomTabBarController : UITabBarController
@end
#import "CustomTabBarController.h"
@implementation CustomTabBarController
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
@end
之后,只需将以下代码添加到UIViewControllers
:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
// Presents the `UIViewController` in landscape orientation when it is first displayed
return UIInterfaceOrientationLandscapeLeft;
}
- (NSUInteger)supportedInterfaceOrientations {
// Allows all other orientations (except upside-down)
return UIInterfaceOrientationMaskAllButUpsideDown;
}
现在,您可以基于每个视图控制器确定首选和支持的方向。 请注意,我没有在我的视图控制器中实现shouldAutorotate
,因为它默认为YES,这是您将视图控制器强制设置为某个方向时想要的(是的,它们应该自动旋转为唯一受支持的方向)。
调用链如下所示:
CustomTabBarController
作为窗口的rootViewController
,以获取受支持/首选的方向 CustomTabBarController
依次询问其selectedViewController
(当前选定选项卡的视图控制器),恰好是我的CustomNavigationController
CustomNavigationController
询问嵌入topViewController
,这是最后的实际UIViewController
实现上述方法的 您仍然需要在构建目标中允许所有设备方向。 当然,您需要更新情节提要/ xib /类以使用这些子类,而不是标准的UINavigationController
和UITabBarController
类。
这种方法的唯一缺点是,至少就我而言,我必须将这些方法添加到我的所有视图控制器中,以使大多数视图控制器仅是纵向的并且具有横向功能。 但是恕我直言,这绝对值得!
您应该将上面的代码编写到UINavigationController
子类中。 您应该定义应用程序方向,并使用if语句分隔视图控制器方向。
-(BOOL)shouldAutorotate {
if ([[self.viewControllers lastObject] isKindOfClass:[UIViewController class]] ) {
return [[self.viewControllers lastObject] shouldAutorotate];
}
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
if ([[self.viewControllers lastObject] isKindOfClass:[UIViewController class]]) {
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.