Можно ли программно переворачивать страницу в UIPageViewController? - PullRequest
151 голосов
/ 26 августа 2011

Можно ли программно перевернуть страницу в UIPageViewController?

Ответы [ 16 ]

1 голос
/ 27 июня 2015

Для одной страницы я только что отредактировал ответ @Jack Humphries

-(void)viewDidLoad
{
  counter = 0;
}
-(IBAction)buttonClick:(id)sender
{
  counter++;
  DataViewController *secondVC = [self.modelController viewControllerAtIndex:counter storyboard:self.storyboard];
  NSArray *viewControllers = nil;          
  viewControllers = [NSArray arrayWithObjects:secondVC, nil];          
  [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
}
1 голос
/ 11 февраля 2013

Мне также нужна была кнопка для перемещения влево на PageViewController, которая должна делать именно то, что вы ожидаете от движения пальцем.

Поскольку внутри " pageViewController: viewControllerBeforeViewController " уже есть несколько правил для работы с естественной прокруткой, я хотел, чтобы кнопка повторно использовала весь этот код, и просто мог не позволяют использовать конкретные индексы для перехода на страницы, как это делали предыдущие ответы. Поэтому мне пришлось принять альтернативное решение.

Обратите внимание, что следующий код предназначен для контроллера просмотра страниц, который является свойством внутри моего пользовательского ViewController, и его позвоночник установлен на середину.

Вот код, который я написал для моей левой кнопки навигации:

- (IBAction)btnNavigateLeft_Click:(id)sender {

    // Calling the PageViewController to obtain the current left page
    UIViewController *currentLeftPage = [_pageController.viewControllers objectAtIndex:0];

    // Creating future pages to be displayed
    NSArray *newDisplayedPages = nil;
    UIViewController *newRightPage = nil;
    UIViewController *newLeftPage = nil;

    // Calling the delegate to obtain previous pages
    // My "pageViewController:viewControllerBeforeViewController" method returns nil if there is no such page (first page of the book).
    newRightPage = [self pageViewController:_pageController viewControllerBeforeViewController:currentLeftPage];
    if (newRightPage) {
        newLeftPage = [self pageViewController:_pageController viewControllerBeforeViewController:newRightPage];
    }

    if (newLeftPage) {
        newDisplayedPages = [[NSArray alloc] initWithObjects:newLeftPage, newRightPage, nil];
    }

    // If there are two new pages to display, show them with animation.
    if (newDisplayedPages) {
        [_pageController setViewControllers:newDisplayedPages direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
    }
}

Вы можете сделать что-то очень похожее, чтобы сделать правильную навигационную кнопку отсюда.

1 голос
/ 21 сентября 2012

Однако использование этого метода «self.pageViewController setViewControllers» не вызывает viewDidDissapear для viewController для страницы, которая была отклонена, тогда как ручное перелистывание страницы вызывает viewDidDissapear на отклоненной странице.Я считаю, что это является причиной моего сбоя

"Количество предоставленных контроллеров представления (0) не соответствует числу, требуемому (1) для запрошенного перехода"

0 голосов
/ 11 апреля 2019

Вот решение с использованием UIPageViewControllerDataSource методов:

Код отслеживает текущий отображаемый контроллер представления в UIPageViewController .

...
@property (nonatomic, strong) UIViewController *currentViewController;
@property (nonatomic, strong) UIViewController *nextViewController;
...

Сначала инициализируйте currentViewController для контроллера начального представления, установленного для UIPageViewController .

- (void) viewDidLoad {
    [super viewDidLoad];
    ...
    self.currentViewController = self.viewControllers[0];
    ...
    [self.pageViewController setViewControllers: @[self.currentViewController] direction: dir animated: YES completion: nil];
}


Затем следите за currentViewController в методах UIPageViewControllerDelegate : pageViewController: willTransitionToViewControllers: и pageViewController: didFinishAnimating: previousViewControllers *: 10 * 246 * 10 * * 10 * 10 * 10 * 10 * 10 *.Наконец, в выбранном вами методе (в приведенном ниже примере это - (IBAction) onNext: (id) отправитель ), вы можете программно переключиться на следующий или предыдущий контроллер, используя UIPageViewControllerDataSouce методы pageViewController: viewControllerBeforeViewController: , pageViewController: viewControllerAfterViewController: , чтобы получить следующий или предыдущий контроллер представления и перейти к нему, вызвав [self.pageViewController setViewControllers]: [@: UIPageViewControllerNavigationDirectionForward анимированный: ДА завершение: ноль];


- (void) onNext {
    UIViewController *vc = [self pageViewController: self.tutorialViewController viewControllerAfterViewController: self.currentViewController];
    if (vc != nil) {
        self.currentViewController = vc;
        [self.tutorialViewController setViewControllers: @[vc] direction: UIPageViewControllerNavigationDirectionForward animated: YES completion: nil];
    }
}

0 голосов
/ 10 июня 2014

Я работаю над этим со вчерашнего дня, и я наконец-то сделал это. Я не мог использовать стандартный шаблон полностью, потому что у меня есть три разных viewControllers как дочерние виды:

1 - rootViewController;
2 - model;
3 - viewControllers
3.1 - VC1;
3.2 - VC2;
3.3 - VC3.
Note: all of VCs has Storyboard ID.

Мне нужна была кнопка запуска только в первом VC, поэтому я добавил одно свойство для pageViewController и модели:

#import <UIKit/UIKit.h>
#import "Model.h"

@interface VC1 : UIViewController

@property (nonatomic, strong) UIPageViewController *thePageViewController;
@property (nonatomic, strong) SeuTimePagesModel *theModel;

@end

Я переписал метод init модели, чтобы передать раскадровку и pageViewController в качестве параметров, чтобы я мог установить их для моего VC1:

- (id)initWithStoryboard:(UIStoryboard *)storyboard
   andPageViewController:(UIPageViewController *)controller
{
    if (self = [super init])
    {
        VC1 *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"VC1"];
        vc1.pageViewController = controller;
        vc1.model = self;

        VC2 *vc2 = [storyboard instantiateViewControllerWithIdentifier:@"VC2"];
        VC3 *vc3 = [storyboard instantiateViewControllerWithIdentifier:@"VC3"];
        self.pageData = [[NSArray alloc] initWithObjects:vc1, vc2, vc3, nil];
    }

    return self;
}

Наконец, я добавил IBAction в свой vc1 для запуска метода pageViewController setViewControllers: direction: animated: завершение: :

- (IBAction)go:(id)sender
{
    VC2 *vc2 = [_model.pages objectAtIndex:1];
    NSArray *viewControllers = @[vc2];
    [_pageViewController setViewControllers:viewControllers
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:YES
                                 completion:nil];
}

Примечание Мне не нужно искать индексы VC, моя кнопка переводит меня на второй VC, но не сложно получить все индексы и отслеживать ваши дочерние представления:

- (IBAction)selecionaSeuTime:(id)sender
{
    NSUInteger index = [_model.pages indexOfObject:self];
    index++;

    VC2 *vc2 = [_model.pages objectAtIndex:1];
    NSArray *viewControllers = @[vc2];
    [_pageViewController setViewControllers:viewControllers
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:YES
                                 completion:nil];
}

Надеюсь, это вам поможет!

0 голосов
/ 20 марта 2014

Как отметил @samwize, способ разбиения на страницы заключается в использовании

setViewControllers:array

Вот как я это сделал: У меня есть источник данных и делегат отдельно. Вы можете вызвать этот метод и изменить только «следующее» представление. Ранее вы должны применять правила подкачки. То есть вы должны проверить направление и следующий контроллер. Если вы используете этот метод со своим пользовательским источником данных, отображаемый массив контроллеров не изменится (поскольку вы будете использовать пользовательский массив в подклассе NSObject).

Используя ваш собственный источник данных, метод просто устанавливает новое представление (с определенным направлением). Поскольку вы все равно будете контролировать страницы, которые будут отображаться при обычном перелистывании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...