Вращение UIPageViewController в контроллере представления контейнера

У меня есть UIViewController, который содержит другие ViewController. Начальный 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;

Этот контроллер контейнера реализовал автоматически ForwardAppearanceAndRotationMethodsToChildViewControllers для возврата 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;
    }];
}

Этот переход отлично работает для моих «обычных» ViewController, и они правильно отображаются после изменения ориентации, даже если они не активны. Однако один из этих контроллеров дочернего представления, называемый SecondCV, имеет UIPageViewController в качестве контроллера дочернего представления. У меня есть UIPageViewControllerDelegate и UIPageViewControllerDataSource, установленные для этого SecondCV, и в pageViewController:spineLocationForInterfaceOrientation: я возвращаю UIPageViewControllerSpineLocationMin для книжной ориентации и UIPageViewControllerSpineLocationMid для альбомной ориентации. Поворот для этого SecondVC работает правильно, когда он активен - две страницы в альбомном режиме и одна в портретном режиме отображаются правильно. Но когда этот SecondVC не активен, вращение неправильное. Даже если вызывается pageViewController:spineLocationForInterfaceOrientation:, остается одна страница как в портретном, так и в альбомном режимах. Я пытаюсь исправить это в течение некоторого времени, но я не вижу других вариантов. У вас есть идеи, как это исправить?

Спасибо.


person DaNY    schedule 13.04.2012    source источник


Ответы (2)


Я решил эту хитрость.

На самом деле 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: и установки двух контроллеров представления для ландшафта, когда SecondVC неактивен, остается только один ViewController в m_pageController в viewWillAppear: после активации SecondVC, остается загадкой для меня.

person DaNY    schedule 25.10.2012
comment
Я также использую контроллер просмотра страниц, и я добавил VC в массив, но не знаю, как правильно переходить между различными VC, как я могу перейти к следующему VC, используя переход скручивания страницы. Не могли бы вы помочь мне в этом или опубликовать пример кода. - person ; 28.11.2012
comment
ссылка Я думаю, вы можете найти здесь все, что нужно, если нет, свяжитесь со мной - person DaNY; 06.12.2012
comment
У меня еще нет решения, пожалуйста, посмотрите на мой вопрос, если вы можете мне помочь. stackoverflow.com/questions/13776894/ - person iPhone Programmatically; 08.12.2012

Я включил следующий код для решения этой проблемы в 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;
}

Надеюсь, это поможет кому-то!

person NicTesla    schedule 15.03.2013