Iphone 在uinavigationcontroller内转换为横向旋转

Iphone 在uinavigationcontroller内转换为横向旋转,iphone,objective-c,cocoa-touch,uinavigationcontroller,Iphone,Objective C,Cocoa Touch,Uinavigationcontroller,我想从UINavigationController中推送一个横向视图,它的初始视图是纵向的。。。 因此,单击按钮或tableviewcell,屏幕将在新视图中旋转90° 我该怎么办?这类似于Youtube应用程序在从电影信息屏幕过渡到实际电影时的工作方式 (注意:我对用户握住设备的旋转方向不感兴趣)实现以下方法,将视图推到导航堆栈上时应调用该方法: - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)int

我想从UINavigationController中推送一个横向视图,它的初始视图是纵向的。。。 因此,单击按钮或tableviewcell,屏幕将在新视图中旋转90°

我该怎么办?这类似于Youtube应用程序在从电影信息屏幕过渡到实际电影时的工作方式


(注意:我对用户握住设备的旋转方向不感兴趣)

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
这应该会在您将其推到堆栈上时自动将所有内容侧向旋转,因为视图不支持纵向

如果我错了,但它没有错,则始终可以通过设置状态栏方向强制水平方向:

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

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
这应该会在您将其推到堆栈上时自动将所有内容侧向旋转,因为视图不支持纵向

如果我错了,但它没有错,则始终可以通过设置状态栏方向强制水平方向:

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

这是我的解决方案,基于本页上的Ed Marty和这里的Simon-

在前面的视图中,从按钮或表格单元格选择的方法调用此函数

- (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];
}

这有点“突然”。你不能真的把动画放在任何一个上面,因为它看起来太浮华了。我想可以通过使用动画(纯黑色视图)推送中间视图,然后自动执行上述操作以转到最终风景图来改进它。

这是我的解决方案,基于本页上的Ed Marty和此处的Simon-

在前面的视图中,从按钮或表格单元格选择的方法调用此函数

- (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];
}

这有点“突然”。你不能真的把动画放在任何一个上面,因为它看起来太浮华了。我想可以通过推一个带有动画的中间视图(纯黑色视图),然后自动执行上述操作以进入最终场景来改进。当从电影信息屏幕过渡到实际电影时,YouTube应用程序中出现的不是导航界面,而是模式视图。这始终可以可靠地工作:如果您以模式显示视图(使用
presentModalViewController
),并且视图只能以一个方向显示,则应用程序将旋转到该方向

因此,解决方案是,不要将您的横向视图推入导航控制器;将其显示为模态视图

好吧,但也许你想骗用户相信我们仍然在导航界面上?然后给模态视图配置一个导航界面,使其看起来像主导航界面!因此,当您呈现模式视图时,它将向用户显示导航界面已旋转(尽管不会出现旋转动画)

现在,唯一的问题是,如果我们查看其根视图,模态视图中的导航界面没有后退按钮。这打破了这种错觉(用户很难再回来)。解决方案是一个技巧:在将横向视图显示为模式视图之前,将其推入导航界面两次。这样,导航界面中显示的是堆栈上的第二个视图,因此有一个后退按钮。然后,在导航控制器委托中,当用户试图返回到您知道的根级别时,点击后退按钮并关闭模式视图。因此:

- (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];
}

从电影信息屏幕过渡到实际电影时,YouTube应用程序中出现的不是导航界面,而是模式视图。这始终可以可靠地工作:如果您以模式显示视图(使用
presentModalViewController
),并且视图只能以一个方向显示,则应用程序将旋转到该方向

因此,解决方案是,不要将您的横向视图推入导航控制器;将其显示为模态视图

好吧,但也许你想骗用户相信我们仍然在导航界面上?然后给模态视图配置一个导航界面,使其看起来像主导航界面!因此,当您呈现模式视图时,它将向用户显示导航界面已旋转(尽管不会出现旋转动画)

现在,唯一的问题是,如果我们查看其根视图,模态视图中的导航界面没有后退按钮。这打破了这种错觉(用户很难再回来)。解决方案是一个技巧:在将横向视图显示为模式视图之前,将其推入导航界面两次。这样,导航界面中显示的是堆栈上的第二个视图,因此有一个后退按钮。然后,在导航控制器委托中,当用户试图返回到您知道的根级别时,点击后退按钮并关闭模式视图。因此:

- (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];
}

嗨,谢谢你的解答。当我将屏幕从横向旋转到纵向,反之亦然多次)时,它会发出内存警告,3-4次旋转后,应用程序会崩溃。您能否建议卸载SecondViewController的正确方法,使其两个实例在被解除后不再占用内存。Thanks@WQS你应该把这当作你自己的另一个问题来问!若内存并没有被释放,你们可能会遇到其他问题。嗨,谢谢你们的解决方案。当我将屏幕从横向旋转到纵向,反之亦然多次)时,它会发出内存警告,3-4次旋转后,应用程序会崩溃。您能否建议卸载SecondViewController的正确方法,使其两个实例在被解除后不再占用内存。Thanks@WQS你应该以不同的方式问这个问题