使用UITabBarController和/或UINavigationController时,仅限某些视图控制器到特定方向

Tob*_*mer 0 objective-c uiviewcontroller uiinterfaceorientation ios landscape-portrait

我在网上搜索得很高,但是找不到明确的答案.UIViewController当嵌入在a中时UINavigationController,只有一种支持横向模式的最佳方法是UITabBarController什么?

像这样的大多数解决方案都建议压倒一切

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
Run Code Online (Sandbox Code Playgroud)

AppDelegate.这有点工作,但是当从唯一ViewController支持横向模式返回时,所有其他(非横向ViewControllers)也将处于横向方向.他们没有保持纵向.

我已经看到应用程序正确,所以我知道它必须以某种方式.例如,电影播放器​​应用程序通常仅限于肖像,但实际的电影播放器​​视图以强制横向模式模式呈现.在解除模态视图控制器后,底层视图控制器仍然正确纵向,

任何提示?

Tob*_*mer 5

经过大量研究后,这是我的结论:

首先,我尝试了实施

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
Run Code Online (Sandbox Code Playgroud)

这里描述的AppDelegate中,适用于大多数情况.但除了感觉相当"hacky"之外,还有一个严重的问题:模态显示的视图控制器的解决方法(参见"模态控制器的一个小问题")在例如显示一个AVPlayerViewController因为它实现了自己的dismiss方法时分解了并且你不能挂钩设置self.isPresented(不幸的viewWillDisappear:是,为时已晚).

于是我就用子类的替代方法UITabBarControllerUINavigationController这感觉干净多了,只稍微详细:

CustomNavigationController

CustomNavigationController.h

#import <UIKit/UIKit.h>

@interface CustomNavigationController : UINavigationController

@end
Run Code Online (Sandbox Code Playgroud)

CustomNavigationController.m

#import "CustomNavigationController.h"

@implementation CustomNavigationController

- (BOOL)shouldAutorotate
{
    return [self.topViewController shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [self.topViewController preferredInterfaceOrientationForPresentation];
}

@end
Run Code Online (Sandbox Code Playgroud)

CustomTabBarController

CustomTabBarController.h

#import <UIKit/UIKit.h>

@interface CustomTabBarController : UITabBarController

@end
Run Code Online (Sandbox Code Playgroud)

CustomTabBarController.m

#import "CustomTabBarController.h"

@implementation CustomTabBarController

- (BOOL)shouldAutorotate
{
    return [self.selectedViewController shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations
{
    return [self.selectedViewController supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}

@end
Run Code Online (Sandbox Code Playgroud)

之后,只需将以下代码添加到您的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;
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以基于每个视图控制器确定首选和支持的方向.请注意,我没有shouldAutorotate在我的视图控制器中实现,因为它默认为YES,如果您的视图控制器应该被强制到某个方向,那么这就是您想要的(是的,它们应该自动旋转到唯一支持的方向).

调用链是这样的:

  • CustomTabBarController,被窗口的rootViewController,被要求支持/择优取向
  • CustomTabBarController又要求其selectedViewController(当前选择的选项卡的视图控制器),这恰好是我的CustomNavigationController
  • 所述CustomNavigationController询问嵌入topViewController,这是最后的实际UIViewController实现上述方法的

您仍然需要允许构建目标中的所有设备方向.当然,您需要更新storyboards/xibs/classes以使用这些子类而不是标准UINavigationControllerUITabBarController类.

这种方法的唯一缺点是,至少在我的情况下,我必须将这些方法添加到我的所有视图控制器中,以使大多数视图控制器仅限肖像和一些支持横向功能.但恕我直言,这绝对是值得的!