如何在 iOS 中处理不同的方向 [英] How to handle different orientations in iOS

查看:20
本文介绍了如何在 iOS 中处理不同的方向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

添加:你可以在github上访问这个项目我希望有'更优雅的方式来做到这一点.

解决方案

使用 -[UIDevice setOrientation:] 是一个私有 API,会导致你的应用程序被拒绝.请参阅这个问题.

您所要求的使用公共 API 是不可能的,并且从 HIG 的角度来看也不推荐. 支持和您应该实现的是具有不同支持界面方向的不同视图控制器的模态呈现.这就是为什么 UINavigationController 的默认实现总是旋转的原因;它假定所有视图控制器都具有相同的受支持界面方向.

以 iPhone 上的视频播放为例.打开视频应用程序(iOS 附带).根视图控制器仅支持纵向.但是,启动视频,会弹出一个仅支持横向界面方向的模态视图控制器.这似乎正是您希望实现的行为.

这就是不调用 preferredInterfaceOrientationForPresentation 的原因.preferredInterfaceOrientationForPresentation 仅在使用 presentViewController:animated: 时被调用.

一个小问题,如果你需要在场景的每个阶段都有一个导航栏,你需要用导航控制器包围每个模态视图控制器.然后,您可以通过访问 segue 中导航控制器对象的 topViewControllerprepareForSegue: 中传递所需的数据.

<小时>

这是一个示例项目,它根据您的要求正确运行(或至少会给您提供如何实施的想法):

http://www.mediafire.com/?zw3qesn8w4v66hy

ADDED: You can access this project on github ios6rotations


Sorry guys for asking the question about screen rotation in iOS 6 but this is really a pain in the ass..and I still can't understand it completely - for some reason it behaves differently under certain circumstances.

I have the following simple hierarchy of views in my test app:

What I'm trying to achieve is - to keep blue controller in landscape only and red one is only in portrait.

I have a subclass of UINavigationController with such code inside:

@implementation CustomNavController

- (BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations
{
    return  [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

In my blue controller I implemented this:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

And in red controller this:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

Now I have the following behavior:

  1. App started in landscape (OK)
  2. When I press the button my red controller pushed in landscape too (this is not ok because it must be shown in Portrait)
  3. It successfully rotates to portrait but not backward to landscape
  4. If I leave the red controller in Portrait mode my blue controller (which is restricted to landscape) shows in Portrait mode.

P.S. All my rotation methods(posted above) are getting called normally.(by the way why do these methods getting called so many times per screen transition - 5-6 times)

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation does not getting called with pushing

All(except portraitUpsideDown) orientations are included in plist.

The question is - how to force rotation to supported orientation in each controller?

I suggest you to post here (as answers) any 100% working code to handle rotations in ios6 (for example if you have some for iPad with SplitController) - I'll keep this question in favorites to have all in one place when I need to handle some specific situations. Cheers!

ADDED: Please do not post this as answer from landscape to portrait I hope that there' s more elegant way to do it.

解决方案

Using -[UIDevice setOrientation:] is a private API, and will get your application rejected. See this question.

What you ask is not possible using public API and is also not recommended from HIG standpoint. What is supported and you should implement, is modal presentation of the different view controllers with different supported interface orientation. This is why the default implementation of UINavigationController is to always rotate; it assumes all view controllers have the same supported interface orientations.

Take for example video playback on iPhone. Open the video apps (that comes with iOS). The root view controller only supports portrait orientation. However, start a video, and a modal view controller pops up which only supports landscape interface orientations. This seems exactly the behavior you wish to achieve.

This is why preferredInterfaceOrientationForPresentation is not called. preferredInterfaceOrientationForPresentation only gets called when using presentViewController:animated:.

A small gotcha, if you require a navigation bar in each stage of your scene, you will need to enclose each modal view controller with a navigation controller. You can then pass the required data in prepareForSegue: by accessing topViewController of the navigation controller object in the segue.


Here is an example project which behaves correctly according to your requirements (or at least will give you ideas how to implement):

http://www.mediafire.com/?zw3qesn8w4v66hy

这篇关于如何在 iOS 中处理不同的方向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆