在 uinavigationcontroller 中过渡到横向旋转

发布于 2024-09-03 09:02:11 字数 184 浏览 4 评论 0原文

我想从 uinaviagtioncontroller 中推送横向视图,其初始视图是纵向的...... 因此,您单击按钮或 tableviewcell,屏幕就会旋转 90° 进入新视图。

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

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

I want to push a landscape view from within a uinaviagtioncontroller, whose initial view is in portrait...
So you click a button, or tableviewcell, and the screen rotates 90° into the new view..

How would I manage that? This is similar to how the Youtube app works when transitioning from movie info screen to the actual movie.

(note: i am not interested in what rotation the user is holding the device)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

伴随着你 2024-09-10 09:02:11

从电影信息屏幕转换到实际电影时,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];
}

What appears in YouTube app when transitioning from the movie info screen to the actual movie is not navigation interface - it's a modal view. This always works reliably: if you show a view modally (using presentModalViewController) and it can appear in only one orientation, the app rotates to that orientation.

So, the solution is, don't push your landscape view into the navigation controller; present it as a modal view.

Okay, but perhaps you want to fool the user into believing that we are still in the navigation interface? Then give the modal view a navigation interface configured to look like the main navigation interface! So when you present the modal view, it will appear to the user as if the navigation interface has rotated (though there will not be a rotation animation).

Now, the only problem is that the navigation interface in the modal view has no Back button if we are looking at its root view. This breaks the illusion (and makes it hard for the user to come back). The solution to that is a trick: push the landscape view twice into the navigation interface before presenting it as a modal view. That way, what is showing in the navigation interface is the second view on the stack, and so there is a Back button. Then, in the navigation controller delegate, catch the Back button and dismiss the modal view when the user tries to return to what you know to be the root level. So:

- (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];
}
一个人的旅程 2024-09-10 09:02:11

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

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

一旦您将其推送到导航堆栈上,这应该会自动横向旋转所有内容,因为视图不支持纵向方向。

如果我错了但事实并非如此,您始终可以通过设置状态栏方向来强制水平方向:

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

Implement the following method, which should be called when the view is pushed onto the navigation stack:

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

This should automatically rotate everything sideways as soon as you push it on to the stack, since the view does not support portrait orientations.

If I'm wrong and it doesn't, you can always force horizontal orientation by setting the status bar orientation:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:animated];
}
捶死心动 2024-09-10 09:02:11

这是我的解决方案,基于本页上的 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];
}

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

This is my solution, based on Ed Marty on this page and Simon here - http://simonwoodside.com/weblog/2009/2/27/iphone_programming_how_to_switch/

Within the preceding view, call this from your button or table cell selected method

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

}

And then within the landscape view

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

It's a bit 'sudden'. You can't really put animation on any of it because it looks too glitchy. I guess it could be improved by pushing a intermediate view with animation (a plain black view) and then automatically doing the above stuff to go to the final landscape.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文