【问题标题】:Maintain one view controller in Portrait and other in Landscape mode iOS在纵向模式下维护一个视图控制器,在横向模式下维护另一个视图控制器 iOS
【发布时间】:2013-12-20 18:05:45
【问题描述】:

我有一个带有 2 个视图控制器的 iOS 应用程序,即 - FirstViewControllerSecondViewController我的窗口的 rootViewController 是 UINavigationController

FirstViewController 应该只能在纵向模式下工作,而 SecondViewController 只能在横向模式下工作。

搜索整个 Stackoverflow 我发现对于 iOS6 及更高版本,我必须在 UINavigationController 上创建一个类别并覆盖 -supportedInterfaceOrientations

问题

从 FirstViewController 开始。现在我的手机处于纵向模式,我按下 SecondViewController,视图以纵向模式加载。一旦我将手机旋转为横向视图,视图将旋转为横向(从此时起将不再返回纵向)。

当我弹回 FirstViewController 时,它将再次处于 Portrait 状态(无论手机的方向如何)。

我希望 SecondViewController 根本不应该以纵向模式显示。我绞尽脑汁……找不到解决办法。

APPDELEGATE

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    ViewController *vc = [[ViewController alloc] init];

    self.navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
    [self.navigationController setNavigationBarHidden:YES];
    self.window.rootViewController = self.navigationController;

    [self.window makeKeyAndVisible];

    return YES;
}

FirstViewController

- (IBAction)btnClicked:(id)sender
{
    SecondViewController *vc = [[SecondViewController alloc] init];
    [self.navigationController pushViewController:vc animated:NO];
}

#pragma mark - Rotation handlers
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

SecondViewController

- (IBAction)btnClicked:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}



#pragma mark - Rotation handlers
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeRight;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeRight;
}

UINavigation 类别

@implementation UINavigationController (Rotation)

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


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

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

【问题讨论】:

  • 屏蔽特定 viewController 上的方向。

标签: ios iphone objective-c


【解决方案1】:

嗯,有点晚了,但这是我的想法。

虽然有很多解决方案可用于 FirstVC 是纵向且第二个可以是纵向和横向的情况,但我找不到任何好的解决方案来解决这个问题(仅限第一个纵向和仅限第二个横向)。这是我所做的:

将两个视图控制器嵌入到它们自己的导航控制器中。创建两个新类,例如 FirstNavController 和 SecondNavController 子类 UINavigationController。使用这些作为您的导航控制器。 (如果您使用 StoryBoards,请选择 Navigation Controller,转到 Identity Inspector 并更改“Class”字段)。

现在,在 FirstNavController 中,添加:

- (BOOL)shouldAutorotate 
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskPortrait;
}

在 SecondNavController 中:

- (BOOL)shouldAutorotate 
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskLandscape;
}

您必须以模态方式呈现 SecondNavController。

在您的视图控制器中不需要做任何事情。确保在应用程序设置中添加所有必需的方向。

此方法的唯一缺点是两个视图不在同一个导航堆栈中,因为第二个视图以模态方式呈现,因此您不会看到后退按钮。但是你可以自己添加一个取消/关闭按钮,然后在 SecondVC 中调用dismissViewControllerAnimated。

【讨论】:

    【解决方案2】:

    在我之前的应用中我已经做到了

    首先你需要启用 Portrait , Landscape left , Landscape right Orientation 来投影

    现在

    将以下代码设置为您的 FirstViewController

    -(void) viewWillAppear:(BOOL)animated{
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]; 
     }
          - (BOOL)shouldAutorotate
     {
           return NO;
     }
    

    将下面的代码设置为您的 secondViewController

    #define degreesToRadian(x) (M_PI * (x) / 180.0)
    
    
     @implementation UINavigationController (Rotation_IOS6)
    
     -(BOOL)shouldAutorotate
    {
     return [[self.viewControllers lastObject] shouldAutorotate];
     }
    
     -(NSUInteger)supportedInterfaceOrientations
     {
       return [[self.viewControllers lastObject] supportedInterfaceOrientations];
     }
    
     @end
     @interface secondViewController ()
    
     @end
    
     @implementation secondViewController
    
    -(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
    
     }
     - (BOOL)shouldAutorotate
    {
       return YES;
    
     }
    
     - (NSUInteger)supportedInterfaceOrientations
     {
        return UIInterfaceOrientationMaskLandscape;
     }
    
    
      @end
    

    【讨论】:

    • 通过使用这样的转换,我只是在愚弄系统相信它处于横向模式。如果我显示 UIAlertView 它仍将处于纵向模式...
    • 如果我们使用导航控制器,这会起作用吗?我不这么认为,因为单个视图上的仿射变换不会改变导航栏、状态栏等。
    • 通过使用上面的代码一切正常 UIAlertView 将显示为横向模式检查它的屏幕截图imm.io/1lvY8
    猜你喜欢
    • 2012-12-09
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多