在uinavigationcontroller中过渡到景观旋转

时间:2010-05-27 16:26:49

标签: iphone objective-c cocoa-touch uinavigationcontroller

我想从一个uinaviagtioncontroller中推出一个横向视图,它的初始视图是纵向的...... 因此,您单击按钮或tableviewcell,屏幕将旋转90°进入新视图..

我将如何管理?这类似于Youtube应用程序在从电影信息屏幕转换为实际电影时的工作方式。

(注意:我对用户持有设备的轮换不感兴趣)

3 个答案:

答案 0 :(得分:2)

实现以下方法,当视图被推送到导航堆栈时应该调用该方法:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

因为视图不支持纵向方向,所以当你将它推到堆栈时,这应该会自动地向侧面旋转所有东西。

如果我错了而且没有,你可以通过设置状态栏方向来强制水平方向:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:animated];
}

答案 1 :(得分:2)

这是我的解决方案,基于Ed Marty在此页面上,Simon在此处 - http://simonwoodside.com/weblog/2009/2/27/iphone_programming_how_to_switch/

在上一个视图中,从您选择的按钮或表格单元格

中调用此方法
- (void) launchLandscape
{
    LandscapeViewController *controller = [[LandscapeViewController alloc] initWithNibName:@"LandscapeViewControllerView" bundle:nil];
    [self.navigationController setNavigationBarHidden:YES];
    controller.hidesBottomBarWhenPushed = YES;
    [[self navigationController] pushViewController:controller animated:NO];
    [controller release];

}

然后在景观视图中

- (void)viewWillAppear:(BOOL)animated { 
    [[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
    CGAffineTransform landscapeTransform = CGAffineTransformMakeRotation( degreesToRadian(90) );
    landscapeTransform = CGAffineTransformTranslate( landscapeTransform, +90.0, +90.0 );
    [self.view setTransform:landscapeTransform];
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
}


-(IBAction)backButton:(id)sender
{
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
    [[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
    [self.navigationController setNavigationBarHidden:NO];
    [self.navigationController popViewControllerAnimated:NO];
}

有点“突然”。你不能真正把动画放在任何一个上,因为它看起来太脆弱了。我想通过推动带有动画的中间视图(纯黑色视图)然后自动执行上述操作以进入最终景观可以改进它。

答案 2 :(得分:2)

从电影信息屏幕转换到实际电影时,YouTube应用中显示的内容不是导航界面 - 它是模态视图。这总是可靠地运行:如果您以模态方式显示视图(使用presentModalViewController)并且它只能以一个方向显示,则应用会旋转到该方向。

所以,解决方法是,不要将景观视图推入导航控制器;把它作为一种模态观点。

好的,但也许你想让用户相信我们还在导航界面?然后给模态视图一个配置为看起来像主导航界面的导航界面!因此,当您呈现模态视图时,它将对用户显示为导航界面已旋转(尽管不会有旋转动画)。

现在,唯一的问题是,如果我们查看其根视图,模态视图中的导航界面没有“后退”按钮。这打破了幻觉(并使用户难以回来)。解决方法是一个技巧:将横向视图两次推入导航界面,然后将其作为模态视图呈现。这样,导航界面中显示的是堆栈上的 second 视图,因此有一个Back按钮。然后,在导航控制器委托中,捕获“后退”按钮并在用户尝试返回到您知道的根级别时关闭模式视图。所以:

- (void) doButton: (id) sender { // appear to navigate into a landscape view
    SecondViewController* sec = [[SecondViewController alloc] init];
    sec.title = self.title; // to give the correct Back button title
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:sec];
    SecondViewController* sec2 = [[SecondViewController alloc] init];
    [nav pushViewController:sec2 animated:NO];
    [self presentModalViewController:nav animated:YES];
    nav.delegate = self; // so that we know when the user navigates back
}

// and here's the delegate method
- (void)navigationController:(UINavigationController *)navigationController 
      willShowViewController:(UIViewController *)viewController 
                    animated:(BOOL)animated {
    if (viewController == [navigationController.viewControllers objectAtIndex:0])
        [self dismissModalViewControllerAnimated:YES];
}