仅支持层次结构中子 UIViewController 的旋转吗?
我有一个子 UIViewController
,它是具有 UITabBarController
和 UINavigationBarController
的层次结构的一部分。我们称之为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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也许您想要的那种行为的最佳模型是 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.