如何在iOS中处理不同的方向

时间:2013-04-11 11:15:59

标签: ios iphone objective-c rotation

增加: 您可以在github上访问此项目 ios6rotations


对于那些在iOS 6中询问有关屏幕旋转的问题的人很抱歉,但这真是一个痛苦的问题......我仍然无法完全理解它 - 出于某些原因,它在某些情况下表现不同。

我的测试应用中有以下简单的视图层次结构:

我想要实现的目标是 - 仅将蓝色控制器保持在横向状态,而红色控制器仅保留为纵向

我有一个UINavigationController的子类,里面有这样的代码:

@implementation CustomNavController

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

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

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

@end

在我的蓝色控制器中,我实现了这个:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

在红色控制器中:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

现在我有以下行为:

  1. 应用程序以横向开始(确定)
  2. 当我按下按钮时,我的红色控制器也被横向推入(这不合适,因为它必须以人像显示)
  3. 成功旋转为纵向但不向后旋转为横向
  4. 如果我将红色控制器置于纵向模式,我的蓝色控制器(仅限横向控制)将以纵向模式显示。
  5. P.S。 所有我的旋转方法(上面发布的)都被正常调用。(顺便说一下为什么这些方法每次屏幕转换被调用这么多次 - 5-6次)

    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation未通过推送

    进行调用

    所有(除了portraitUpsideDown)方向都包含在plist中。

    问题是 - 如何在每个控制器中强制旋转到支持的方向?

    我建议你在这里(作为答案)发布任何100%工作代码来处理ios6中的旋转(例如,如果你有一些用于带有SplitController的iPad) - 我会将这个问题保留在收藏夹中以便将所有内容放在一个地方当我需要处理某些特定情况时。干杯!

    增加: 请不要将其发布为答案from landscape to portrait我希望那里有' 更优雅的方式。

6 个答案:

答案 0 :(得分:27)

使用-[UIDevice setOrientation:]是一个私有API,会让您的申请被拒绝。请参阅this question

您要求使用公共API是不可能的,也不建议从HIG的角度来看。支持和实现的是具有不同支持的界面方向的不同视图控制器的模态显示。这就是UINavigationController的默认实现始终是旋转的原因;它假设所有视图控制器都具有相同的支持接口方向。

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

这就是为什么不调用preferredInterfaceOrientationForPresentation的原因。 preferredInterfaceOrientationForPresentation仅在使用presentViewController:animated:时被调用。

如果在场景的每个阶段都需要导航栏,则需要使用导航控制器封装每个模态视图控制器。然后,您可以通过访问segue中导航控制器对象的prepareForSegue:来传递topViewController中的所需数据。


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

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

答案 1 :(得分:6)

我的两分钱。

您可以快速提供 空透明模式视图,然后将其关闭 ,也可以在ViewDidLoad:或ViewWillAppear上显示ViewController和ViewControllerSecond类作为快速解决方法。

此外,在storyboard中,您可以直观地将 ViewController 类方向设置为 landscape

答案 2 :(得分:3)

使用此行以编程方式更改方向... 工作100%

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];

并且当你在此时添加此行时会出现一个警告,并且要删除此警告,只需在您的实现文件上添加以下代码..在顶部。

@interface UIDevice (MyPrivateNameThatAppleWouldNeverUseGoesHere)
- (void) setOrientation:(UIInterfaceOrientation)orientation;
@end

然后在波纹管方法中,只需要编写此代码..

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return your supported orientations

 if (currentMainView==blueOne) {
        return toInterfaceOrientation== UIInterfaceOrientationPortrait;
    }
}

答案 3 :(得分:3)

我的一个应用程序中有类似的情况(虽然请注意我没有使用UINavigationController)。

更改两个viewControllers中的shouldAutorotate方法:

//in blue (landscape only)
-(BOOL)shouldAutorotate{
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
        return YES;
    }
    else {
        return NO;
    }
}

//in red (portrait only)
-(BOOL)shouldAutorotate{
    if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {
        //note that UIInterfaceOrientationIsPortrait(self.interfaceOrientation) will return yes for UIInterfaceOrientationPortraitUpsideDown
        return YES;
    }
    else {
        return NO;
    }
}

保持supportedInterfaceOrientations方法不变。

答案 4 :(得分:0)

#pragma mark- Orientation Delegate Method:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{   Orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (Orientation == UIInterfaceOrientationLandscapeLeft || Orientation == UIInterfaceOrientationLandscapeRight)
    {

        // self.scrollView.contentOffset = CGPointMake(self.view.bounds.size.width,1200);

        [scrollView setScrollEnabled:YES];
        [scrollView setContentSize:CGSizeMake(768, 2150)];


    }else if (Orientation == UIInterfaceOrientationPortrait || Orientation == UIInterfaceOrientationPortraitUpsideDown)
    {

        [scrollView setScrollEnabled:YES];
        [scrollView setContentSize:CGSizeMake(768, 1750)];

    }

}

答案 5 :(得分:-2)

为了一起使用带有方向的导航,你应该像一个数组一样使用一堆viewcontrollers。

按照方法检查后

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

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

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

这种方法的改变对你有很大的帮助。

享受编程!