在容器视图控制器中旋转UIPageViewController

时间:2012-04-13 08:16:30

标签: containers uipageviewcontroller screen-rotation

我有一个包含其他ViewControllers的UIViewController。初始ViewController在viewDidLoad中设置:

FirstViewController *first = [FirstViewController alloc] init];
first.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
first.view.frame = m_content.frame;

[self addChildViewController:first];
[m_content.view addSubview:first.view];
[first didMoveToParentViewController:self];
m_activeViewController = first;

此容器控制器已实现 automaticForwardAppearanceAndRotationMethodsToChildViewControllers 以返回YES。它还实现了将旋转更改手动转发到非活动ViewControllers

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    for(UIViewController *vc in m_viewControllers)
    {
        if(vc != [m_activeViewController]
            [vc willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    }
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    for(UIViewController *vc in m_viewControllers)
    {
        if(vc != [m_activeViewController]
            [vc didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    }
}

点击菜单按钮后,我在ViewControllers之间进行转换。

- (void)onMenuItemTapped:(id)sender
{
    UIViewController *vc = [m_viewControllers objectAtIndex:sender.tag];

    vc.view.frame = m_content.frame;
    [self addChildViewController:vc];
    [self transitionFromViewController:m_activeViewController toViewController:vc duration:0 options:UIViewAnimationOptionTransitionNone animations:nil completion:^(BOOL finished) {
    [vc didMoveToParentViewController:self];
    [m_activeViewController removeFromParentViewController];
    m_activeViewController = vc;
    }];
}

此转换适用于我的“普通”ViewControllers,它们在方向更改后正确显示,即使它们未处于活动状态。但是,其中一个名为SecondCV的子视图控制器具有 UIPageViewController 作为子视图控制器。我将 UIPageViewControllerDelegate UIPageViewControllerDataSource 设置为此SecondCV,并在 pageViewController中:spineLocationForInterfaceOrientation:我为Portrait返回UIPageViewControllerSpineLocationMin,为Landscape返回UIPageViewControllerSpineLocationMid。此活动的旋转在活动时正常工作 - 横向上有两个页面,纵向模式上有一个页面正确显示。但是当此SecondVC未激活时,旋转不正确。即使调用 pageViewController:spineLocationForInterfaceOrientation:,在纵向和横向模式下仍然有一个页面。我试图解决这个问题一段时间,但我没有看到任何其他选择。你有任何想法如何解决这个问题?

谢谢。

2 个答案:

答案 0 :(得分:1)

我已经解决了这种棘手的问题。

实际上,SecondVC正确旋转,或者至少脊柱位置已正确更改。因此,当我旋转设备并且父视图中的SecondVC不是活动视图控制器时, HAS 收到了旋转消息,并且还调用了 pageViewController:spineLocationForInterfaceOrientation:。我为新的界面方向设置了正确的脊椎位置,并将 setViewControllers 设置为SecondVC的页面视图控制器。问题是,即使我为 UIPageViewControllerSpineLocationMid 设置了两个视图控制器,在显示SecondVC之后仍然只有一个,就像在UIPageViewControllerSpineLocationMin中一样。

通过再次在 viewWillAppear:中将视图控制器设置为页面视图控制器,我已经“修复”了这个问题,因为调用此方法时,页面视图控制器的主干位置是正确的并且基于此信息我设置一个或两个页面(视图控制器)

- (void)viewWillAppear:(BOOL)animated
{
if(m_pageController.spineLocation == UIPageViewControllerSpineLocationMid)
{
    LeftPageController *left;
    RightPageController *right;
    if(m_pageController.viewControllers.count > 0)
    {
        left = [m_pageController.viewControllers objectAtIndex:0];

        right = [m_storyboard instantiateViewControllerWithIdentifier:@"rightPage"];
        [right loadView];
    }

    [m_pageController setViewControllers:[NSArray arrayWithObjects:left, right, nil] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];

    [m_left hideGallery];
}

if(m_pageController.spineLocation == UIPageViewControllerSpineLocationMin)
{

    [m_pageController setViewControllers:[NSArray arrayWithObject:[m_pageController.viewControllers objectAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
}

[super viewWillAppear:animated];
}


- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if(UIInterfaceOrientationIsPortrait(orientation))
{
    LeftPageController *left = [pageViewController.viewControllers objectAtIndex:0];
    [pageViewController setViewControllers:[NSArray arrayWithObject:left] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];

    pageViewController.doubleSided = NO;     

    return UIPageViewControllerSpineLocationMin;
}

if(UIInterfaceOrientationIsLandscape(orientation))
{    
    LeftPageController *left;
    RightPageController *right;
    if(pageViewController.viewControllers.count > 0)
    {
        left = [pageViewController.viewControllers objectAtIndex:0];
        right = [m_storyboard instantiateViewControllerWithIdentifier:@"rightPage"];
        [right loadView];
    }

    [pageViewController setViewControllers:[NSArray arrayWithObjects:left,right, nil] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];

    return UIPageViewControllerSpineLocationMid;
}

return UIPageViewControllerSpineLocationMin;
}

我知道我两次做同样的事情,但这就是我愿意支付的价格。为什么在调用 pageViewController:spineLocationForInterfaceOrientation:并为Landscape设置两个视图控制器后,当SecondVC处于非活动状态时,激活SecondVC后, viewWillAppear:中的m_pageController中只有一个ViewController保持神秘感我

答案 1 :(得分:0)

我在iOS 6中包含以下代码来解决此问题:

- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{

    NSArray *allPageControllers = pageViewController.viewControllers

    if (allPageControllers != nil) {
       [self setViewControllers:allPageControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    }

    else {

       UIViewController *defaultViewController = [[UIViewController alloc] init];
       [self setViewControllers:[NSArray arrayWithObject:defaultViewController] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
       [defaultViewController release];
    }

    return UIPageViewControllerSpineLocationMin;
}

希望它有所帮助!