19

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.

4

6 回答 6

26

使用-[UIDevice setOrientation:]的是私有 API,会导致您的应用程序被拒绝。看到这个问题

使用公共 API 无法实现您的要求,从 HIG 的角度来看也不建议这样做。支持并且您应该实现的是具有不同支持的界面方向的不同视图控制器的模式表示。这就是为什么默认实现UINavigationController是始终旋转的原因;它假定所有视图控制器都具有相同的受支持界面方向。

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

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

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


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

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

于 2013-04-15T18:49:40.200 回答
6

我的两分钱值。

您可以在 ViewController 和 ViewControllerSecond 类上快速显示一个空的透明模态视图,然后将其关闭,也许是在 ViewDidLoad: 或 viewWillAppear: 上作为快速解决方法。

此外,在情节提要中,您可以将ViewController类的方向设置为视觉上的横向。

于 2013-04-16T09:49:18.260 回答
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;
    }
}
于 2013-04-15T08:14:06.790 回答
3

我在我的一个应用程序中遇到了类似的情况(尽管请注意我没有使用 UINavigationController)。

更改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方法相同。

于 2013-04-17T01:20:51.107 回答
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)];

    }

}
于 2015-03-05T07:02:29.673 回答
-2

为了一起使用导航和方向,您应该使用一堆视图控制器,如数组。

之后结帐以下方法,

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

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

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

您方法的这种变化将对您有很大帮助。

享受编程!

于 2013-04-11T11:30:55.137 回答