仅支持层次结构中子 UIViewController 的旋转吗?

发布于 2024-12-13 17:01:03 字数 2260 浏览 0 评论 0原文

我有一个子 UIViewController ,它是具有 UITabBarControllerUINavigationBarController 的层次结构的一部分。我们称之为ChildViewController;那么我的层次结构如下所示:

UITabBarController
  |
  UINavigationViewController [tab 1]
    |
    SomeParentViewController
      |
      SomeOtherParentViewController
        |
        ChildViewController

现在我只想 ChildViewController 支持旋转到横向。 (它是一个显示聊天视图的视图控制器,横向模式更容易打字。)我添加了方法 - (BOOL) shouldAutorotateToInterfaceOrientation:ChildViewController 来声明它支持横向方向,但旋转设备没有效果。通过调试,我发现 – willAnimateRotationToInterfaceOrientation:duration: 没有被调用。

经过一些在线搜索后,我发现 UITabBarController 的后代仅在 UITabBarController 本身支持给定方向的情况下支持该方向。而且,奇怪的是,如果每个选项卡的视图控制器都支持旋转,则 UITabBarController 仅支持方向。与上面的选项卡 1 一样,其他三个选项卡的视图控制器是 UINavigationViewController 实例;而且,因为我们必须更深入,所以每个 UINavigationViewController 仅当其子视图控制器支持方向时才支持方向。

因此,此时,将 - (BOOL) shouldAutorotateToInterfaceOrientation: 添加到 SomeParentViewController 以及其他 UINavigationController 实例的子级允许 ChildViewController< /code> 进行旋转。但现在 SomeParentViewController 和其他三个选项卡将旋转为横向,看起来很糟糕。我只希望 ChildViewController 支持横向。

作为一项闩沟努力,我创建了自己的 UITabBarController 子类,名为 RotatingUITabBarController ,并向 ChildViewController 类添加一个全局标志,让我知道它是否已创建并显示。 RotatingUITabBarController 仅覆盖 - (BOOL) shouldAutorotateToInterfaceOrientation: 并实现为:

if ([ChildViewController isDisplayed]) {
  return ((toInterfaceOrientation == UIInterfaceOrientationPortrait) ||
      (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
      (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
return NO;

现在,如果我启动应用程序,切换到 SomeParentViewController 或任何其他Tab 并旋转手机不会切换到横向模式,而是保持纵向模式。到目前为止,一切都很好。如果我创建并显示 ChildViewController 并旋转手机,它就会进入横向。到目前为止,一切都很好。但现在如果我弹出 ChildViewController 以显示 SomeOtherParentViewController,它也是横向的。 SomeParentViewController 和我切换到的所有其他选项卡也是如此。

我现在已经没有技巧了。任何建议将不胜感激,谢谢!

I have a child UIViewController with that's part of a hierarchy with a UITabBarController and a UINavigationBarController. Let's call it ChildViewController; then my hierarchy looks like:

UITabBarController
  |
  UINavigationViewController [tab 1]
    |
    SomeParentViewController
      |
      SomeOtherParentViewController
        |
        ChildViewController

Now I want only ChildViewController to support rotation to landscape orientation. (It's a view controller that shows a chat view, and the landscape mode is easier for typing for some.) I added method - (BOOL) shouldAutorotateToInterfaceOrientation: to ChildViewController to declare that it supports landscape orientation, but rotating the device had no effect. From debugging, I found that – willAnimateRotationToInterfaceOrientation:duration: wasn't being called.

After some searching around online, I've found that a descendent of a UITabBarController only supports a given orientation if the UITabBarController itself supports that orientation. And, strangely enough, UITabBarController only supports an orientation if the view controllers for each of its tabs support rotation. Like tab 1 above, the view controllers for the other three tabs are UINavigationViewController instances; and, because we must go deeper, each UINavigationViewController only supports orientation if its child view controller supports the orientation.

So at this point, adding adding - (BOOL) shouldAutorotateToInterfaceOrientation: to SomeParentViewController and the children of the other UINavigationController instances allowed ChildViewController to rotate. But now SomeParentViewController and the other three tabs will rotate to landscape, and it looks horrible. I only wanted ChildViewController to support landscape.

As a latch ditch effort, I created my own UITabBarController subclass called RotatingUITabBarController and add a global flag to the ChildViewController class that lets me know if it has been created and is displayed. The RotatingUITabBarController overrides only - (BOOL) shouldAutorotateToInterfaceOrientation: and is implemented as:

if ([ChildViewController isDisplayed]) {
  return ((toInterfaceOrientation == UIInterfaceOrientationPortrait) ||
      (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
      (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
return NO;

Now, if I boot the app, switching to SomeParentViewController or any other tab and rotating the phone does not switch to landscape mode, instead keeping in portrait. So far so good. If I create and display ChildViewController and rotate the phone, it enters landscape. So far so good. But now if I pop ChildViewController to reveal SomeOtherParentViewController, it is also in landscape. And so is SomeParentViewController and every other tab that I switch to.

I'm out of tricks now. Any advice would be much appreciated, thanks!

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

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

发布评论

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

评论(1

凉薄对峙 2024-12-20 17:01:03

也许您想要的那种行为的最佳模型是 YouTube 应用程序。大多数界面都是纵向的,但播放视频的视图可以纵向或横向工作。

如果您查看该应用程序,您会注意到 UI 的整个选项卡部分实际上是一个模式视图控制器。当您启动应用程序时,标签栏控制器会立即以模态方式呈现。您离开模态选项卡栏控制器的唯一时间是在播放视频时 - 您会注意到整个选项卡式界面向下滑动以显示视频视图。当视频结束时,标签栏控制器再次以模态呈现。

这是“正常”方法的反转,您仅短暂使用模态视图控制器,但它在 YouTube 应用程序中运行良好。它可能也可能适合你,也可能不适合你。重要的是让您的应用程序具有可预测性和流畅性,并让用户始终感觉一切尽在掌控。

Perhaps the best model for the kind of behavior you seem to want is the YouTube app. Most the interface is portrait-only, but the view that plays videos works in either portrait or landscape.

If you look at that app, you'll notice that the whole tabbed part of the UI is actually a modal view controller. When you launch the app, the tab bar controller is immediately presented modally. The only time you leave that modal tab bar controller is when you play a video -- you'll notice that the whole tabbed interface slides down to reveal the video view. When the video ends, the tab bar controller is again presented modally.

This is an inversion of the "normal" approach, where you use a modal view controller only briefly, but it works very well in the YouTube app. It may or may not work well for you too. The important thing is to make your app predictable and fluid, and make the user feel in control at all times.

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