iOS6自动旋转 - UIPageViewController

时间:2012-09-24 16:00:51

标签: iphone ios cocoa-touch ipad ios6

我的UI结构:

UINavigationController
--UIViewController(first)
 |
 |Modal 
 |
 V 
UINavigationController (subclass)
--UIViewController (contains UIPageViewController)

对于iOS6的新自动旋转,我创建了一个UINavigationController的子类并添加了:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

只想保持方向为肖像。

我初始化UIPageViewController,如:

self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

    PageDataViewController *startingViewController = [self viewControllerAtIndex:start storyboard:self.storyboard];

    NSArray *viewControllers = [NSArray arrayWithObject:startingViewController];
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];

    self.pageViewController.dataSource = self;

    [self addChildViewController:self.pageViewController];
    [self.view addSubview:self.pageViewController.view];

    // Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
    CGRect pageViewRect = self.view.bounds;
    self.pageViewController.view.frame = pageViewRect;

    [self.pageViewController didMoveToParentViewController:self];

然后我执行Modal segue, 如果第一个UIViewController是肖像,则pageViewController工作, 但如果第一个UIViewController是横向的,我总是有例外:

  

*断言失败 - [UIPageViewController willAnimateRotationToInterfaceOrientation:duration:],   /SourceCache/UIKit_Sim/UIKit-2372/UIPageViewController.m:945    由于未捕获的异常'NSInternalInconsistencyException'而终止应用,原因:'没有视图控制器'   * *第一次调用堆栈:(0x2a5e012 0x19bae7e 0x2a5de78 0x1450f35 0xd75974 0x9f12b4 0x9f13ea 0x9e4c32 0x9f1372 0x9f13ea 0x9e4c32   0x9f1372 0x9f1751 0x93a1a6 0xbee5f9 0x9ec4f3 0x9ec777 0x9ec7b7   0xd57fe2 0xd49ad9 0xd49b54 0x9b1899 0x9b1b3d 0x13b8e83 0x2a1d376   0x2a1ce06 0x2a04a82 0x2a03f44 0x2a03e1b 0x2c967e3 0x2c96668 0x90265c   0xea7d 0x2685 0x1)libc ++ abi.dylib:终止调用throw a   例外

4 个答案:

答案 0 :(得分:4)

实际上有另一种解决方案。

旋转只是调用willAnimateRotationToInterfaceOrientation方法到rootViewController,你必须实现它的方法。

@interface UIPageViewController (Rotation)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
@end

//实施文件

#import "UIPageViewController+Rotation.h"

@implementation UIPageViewController(Rotation)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {}
@end

答案 1 :(得分:2)

在关于“supportedInterfaceOrientations”的文档中写道:

  

当用户更改设备方向时,系统会在根视图控制器或填充窗口的最顶层显示视图控制器上调用此方法

您是否尝试将主窗口的rootViewController设置为当前的NavigationController类?

就像在AppDelegate中一样:

self.window.rootViewController = nvc;

当你的navigationController发生变化时,再次设置rootViewController ......

答案 2 :(得分:0)

我已经修复了#34;通过再次在UIPageViewController中将视图控制器设置为viewWillAppear:来解决问题,因为调用此方法时,页面视图控制器的主干位置是正确的,并根据此信息设置一页或两页(查看控制器)

- (void)viewWillAppear:(BOOL)animated
{   
    [super viewWillAppear:animated];

    if(self.pageViewController.spineLocation == UIPageViewControllerSpineLocationMid)
    {
        BookPageViewController *currentViewController = self.pageViewController.viewControllers[0];
        NSArray *viewControllers = nil;

        NSUInteger indexOfCurrentViewController = [self.modelController indexOfViewController:currentViewController];
        if (indexOfCurrentViewController == 0 || indexOfCurrentViewController % 2 == 0) {
            UIViewController *nextViewController = [self.modelController pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController];
            viewControllers = @[currentViewController, nextViewController];
        } else {
            UIViewController *previousViewController = [self.modelController pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController];
            viewControllers = @[previousViewController, currentViewController];
        }
        [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
    }

    if(self.pageViewController.spineLocation == UIPageViewControllerSpineLocationMin)
    {
        [self.pageViewController setViewControllers:[NSArray arrayWithObject:[self.pageViewController.viewControllers objectAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
    }
}

并设置UIPageViewController委托方法如下

- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
    BookPageViewController *currentViewController = self.pageViewController.viewControllers[0];

    if(UIInterfaceOrientationIsPortrait(orientation))
    {
        [self.pageViewController setViewControllers:[NSArray arrayWithObject:currentViewController] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];

        pageViewController.doubleSided = NO;

        return UIPageViewControllerSpineLocationMin;
    }

    if(UIInterfaceOrientationIsLandscape(orientation))
    {
        NSArray *viewControllers = nil;

        NSUInteger indexOfCurrentViewController = [self.modelController indexOfViewController:currentViewController];
        if (indexOfCurrentViewController == 0 || indexOfCurrentViewController % 2 == 0) {
            UIViewController *nextViewController = [self.modelController pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController];
            viewControllers = @[currentViewController, nextViewController];
        } else {
            UIViewController *previousViewController = [self.modelController pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController];
            viewControllers = @[previousViewController, currentViewController];
        }
        [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];

        return UIPageViewControllerSpineLocationMid;
    }

    return UIPageViewControllerSpineLocationMin;
}

答案 3 :(得分:0)

我通过在viewWillAppear中将视图控制器设置为UIPageViewController来解决问题:再次,因为调用此方法时,页面视图控制器的主干位置是正确的,并根据此信息设置一页或两页(查看控制器)