¿Es posible pasar la página mediante programación en UIPageViewController?

161

¿Es posible pasar la página mediante programación UIPageViewController?

RAGOpoR
fuente
1
¿Puedes publicar algún código de ejemplo? Agradecido a ti.
iPhone programáticamente el

Respuestas:

235

Sí, es posible con el método:

- (void)setViewControllers:(NSArray *)viewControllers 
                 direction:(UIPageViewControllerNavigationDirection)direction 
                  animated:(BOOL)animated 
                completion:(void (^)(BOOL finished))completion;`

Ese es el mismo método utilizado para configurar el primer controlador de vista en la página. De manera similar, puede usarlo para ir a otras páginas.

¿Me pregunto por qué viewControllerses una matriz y no un solo controlador de vista?

Esto se debe a que un controlador de vista de página podría tener una "columna vertebral" (como en iBooks), que muestra 2 páginas de contenido a la vez. Si muestra 1 página de contenido a la vez, simplemente pase una matriz de 1 elemento.

Un ejemplo en Swift:

pageContainer.setViewControllers([displayThisViewController], direction: .Forward, animated: true, completion: nil)
samwize
fuente
2
Ahora que el NDA está activo, ¿se puede ampliar esto un poco más? Quizás una muestra de código.
SpaceTrucker 01 de
11
Creo que finalmente entiendo esto: a UIPageViewController realmente no le importa en qué página se encuentra actualmente. Cuando llama a setViewControllers, puede hacer que parezca que se está alejando animadamente del controlador de vista actual, pero en realidad no está buscando una página.
Amy
3
ejemplo: [self setViewControllers: @ [vcToMoveTo] dirección: UIPageViewControllerNavigationDirectionForward animado: SI finalización: nulo]; // donde vcToMoveTo es un UIViewController
finneycanhelp
1
Si desea seguir utilizando UIPageControl, entonces es posible que desee: self.currentIndex = índice de viewControllerToMoveTo luego de regreso presentationIndexForPageViewController self.currentIndex
Brendan
3
Consulte stackoverflow.com/questions/22554877/… si también necesita actualizar la pantalla del indicador de página
Protongun
37

Como también necesitaba esto, entraré en más detalles sobre cómo hacerlo.

Nota: Supongo que usó el formulario de plantilla estándar para generar su UIPageViewControllerestructura, que tiene tanto el modelViewControllery dataViewControllercreado cuando lo invoca. Si no comprende lo que escribí, regrese y cree un nuevo proyecto que use el UIPageViewControllercomo base. Entonces lo entenderás.

Por lo tanto, la necesidad de pasar a una página en particular implica configurar las diversas partes del método enumerado anteriormente. Para este ejercicio, supongo que es una vista de paisaje con dos vistas que se muestran. Además, implementé esto como una IBAction para que se pueda hacer presionando un botón o no, es igual de fácil hacer que el selector llame y pase los elementos necesarios.

Entonces, para este ejemplo, necesita los dos controladores de vista que se mostrarán, y opcionalmente, ya sea que avance en el libro o retroceda.

Tenga en cuenta que simplemente codifiqué dónde ir a las páginas 4 y 5 y utilizo un deslizamiento hacia adelante. Desde aquí puede ver que todo lo que necesita hacer es pasar las variables que lo ayudarán a obtener estos elementos ...

-(IBAction) flipToPage:(id)sender {

    // Grab the viewControllers at position 4 & 5 - note, your model is responsible for providing these.  
    // Technically, you could have them pre-made and passed in as an array containing the two items...

    DataViewController *firstViewController = [self.modelController viewControllerAtIndex:4 storyboard:self.storyboard];
    DataViewController *secondViewController = [self.modelController viewControllerAtIndex:5 storyboard:self.storyboard];

    //  Set up the array that holds these guys...

    NSArray *viewControllers = nil;

    viewControllers = [NSArray arrayWithObjects:firstViewController, secondViewController, nil];

    //  Now, tell the pageViewContoller to accept these guys and do the forward turn of the page.
    //  Again, forward is subjective - you could go backward.  Animation is optional but it's 
    //  a nice effect for your audience.

      [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];

    //  Voila' - c'est fin!  

}
Joe
fuente
2
Tengo el mismo requisito para pasar a una página específica. Pero el código anterior no parece funcionar para mí. ¿Qué estoy haciendo mal? Tengo 19 paginas.
GaneshT
¿Podemos usar este fragmento de código también al proporcionar los controladores de vista a través de un objeto de origen de datos?
Jens Kohl el
20
Qué clase extrañamente mal implementada, Apple.
devios1
29

Aquí hay otro ejemplo de código para una sola vista paginada. La implementación de viewControllerAtIndex se omite aquí, debería devolver el controlador de vista correcto para el índice dado.

- (void)changePage:(UIPageViewControllerNavigationDirection)direction {
    NSUInteger pageIndex = ((FooViewController *) [_pageViewController.viewControllers objectAtIndex:0]).pageIndex;

    if (direction == UIPageViewControllerNavigationDirectionForward) {
        pageIndex++;
    }
    else {
        pageIndex--;
    }

    FooViewController *viewController = [self viewControllerAtIndex:pageIndex];

    if (viewController == nil) {
        return;
    }

    [_pageViewController setViewControllers:@[viewController]
                                  direction:direction
                                   animated:YES
                                 completion:nil];
}

Las páginas pueden cambiarse llamando

[self changePage:UIPageViewControllerNavigationDirectionReverse];
[self changePage:UIPageViewControllerNavigationDirectionForward];
lekksi
fuente
Pero el control de índice de página no se actualiza. ¿Cómo puedo hacer eso?
thatzprem
1
Esta respuesta funciona para mí; tenga en cuenta que si confía en los métodos de delegado "didFinishAnimating" de UIPageViewController, no se activarán. En cambio, mueva su código de didFinishAnimating a un método separado y llame a ese método desde el bloque de finalización en el método setViewControllers.
DiscDev
1
@thatzprem Si desea seguir utilizando UIPageControl, entonces usted puede desear: self.currentIndex = índice de viewControllerToMoveTo luego de regreso presentationIndexForPageViewController self.currentIndex
Brendan
@thatzprem tiene razón. Cada vez va a la misma página. Por ejemplo, si tenemos 3 páginas, cada vez irá solo a la 2da página.
Tushar Lathiya
18

Podría estar perdiendo algo aquí, pero esta solución parece mucho más simple que muchas otras propuestas.

extension UIPageViewController {
    func goToNextPage(animated: Bool = true, completion: ((Bool) -> Void)? = nil) {
        if let currentViewController = viewControllers?[0] {
            if let nextPage = dataSource?.pageViewController(self, viewControllerAfter: currentViewController) {
                setViewControllers([nextPage], direction: .forward, animated: animated, completion: completion)
            }
        }
    }
}
wfbarksdale
fuente
1
¡Funciona genial! Solo tengo que cambiar también el indicador de página de alguna manera.
TruMan1
¡De mucha ayuda! Danos también una función para goToFirstPage.
Mamta
Cada vez va a la misma página. Por ejemplo, si tenemos 3 páginas, cada vez irá solo a la 2da página.
Tushar Lathiya
15

Este código funcionó muy bien para mí, gracias.

Esto es lo que hice con eso. Algunos métodos para avanzar o retroceder y uno para ir directamente a una página en particular. Es para un documento de 6 páginas en vista vertical. Funcionará bien si lo pega en la implementación del RootController de la plantilla pageViewController.

-(IBAction)pageGoto:(id)sender {

    //get page to go to
    NSUInteger pageToGoTo = 4;

    //get current index of current page
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers   objectAtIndex:0];
    NSUInteger retreivedIndex = [self.modelController indexOfViewController:theCurrentViewController];

    //get the page(s) to go to
    DataViewController *targetPageViewController = [self.modelController viewControllerAtIndex:(pageToGoTo - 1) storyboard:self.storyboard];

    DataViewController *secondPageViewController = [self.modelController viewControllerAtIndex:(pageToGoTo) storyboard:self.storyboard];

    //put it(or them if in landscape view) in an array
    NSArray *theViewControllers = nil;    
    theViewControllers = [NSArray arrayWithObjects:targetPageViewController, secondPageViewController, nil];


    //check which direction to animate page turn then turn page accordingly
    if (retreivedIndex < (pageToGoTo - 1) && retreivedIndex != (pageToGoTo - 1)){
        [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
    }

    if (retreivedIndex > (pageToGoTo - 1) && retreivedIndex != (pageToGoTo - 1)){
        [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:NULL];
    }

}


-(IBAction)pageFoward:(id)sender {

    //get current index of current page
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
    NSUInteger retreivedIndex = [self.modelController indexOfViewController:theCurrentViewController];

    //check that current page isn't first page
    if (retreivedIndex < 5){

        //get the page to go to
        DataViewController *targetPageViewController = [self.modelController viewControllerAtIndex:(retreivedIndex + 1) storyboard:self.storyboard];

        //put it(or them if in landscape view) in an array
        NSArray *theViewControllers = nil;    
        theViewControllers = [NSArray arrayWithObjects:targetPageViewController, nil];

        //add page view
        [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];

    }

}


-(IBAction)pageBack:(id)sender {


    //get current index of current page
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
    NSUInteger retreivedIndex = [self.modelController indexOfViewController:theCurrentViewController];

    //check that current page isn't first page
    if (retreivedIndex > 0){

    //get the page to go to
    DataViewController *targetPageViewController = [self.modelController viewControllerAtIndex:(retreivedIndex - 1) storyboard:self.storyboard];

    //put it(or them if in landscape view) in an array
    NSArray *theViewControllers = nil;    
    theViewControllers = [NSArray arrayWithObjects:targetPageViewController, nil];

    //add page view
    [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:NULL];

    }

}
Graham
fuente
Quiero usarlo para el modo horizontal donde existen dos páginas. cómo usarlo allí. ¿Puedes por favor guiar?
iPhone programáticamente
9

Swift 4:

Necesitaba ir al siguiente controlador cuando toco el siguiente en un controlador de vista de controlador de página y también actualizar el índice de control de página, por lo que esta fue la mejor y más directa solución para mí :

let pageController = self.parent as! PageViewController

pageController.setViewControllers([parentVC.orderedViewControllers[1]], direction: .forward, animated: true, completion: nil)

pageController.pageControl.currentPage = 1
Sam Bing
fuente
5

¿Qué pasa con el uso de métodos de dataSource?

UIViewController *controller = [pageViewController.dataSource pageViewController:self.pageViewController viewControllerAfterViewController:pageViewController.viewControllers.firstObject];
[pageViewController setViewControllers:@[controller] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

Analógicamente para atrás.

JakubKnejzlik
fuente
3

En Swift :

import UIKit

extension HomeViewController {

    // MARK: - Carousel management.

    func startTimerForMovingCarousel(let numberOfSecondsBetweenFiringsOfTheTimer: NSTimeInterval) {
        if (self.timerForMovingCarousel == nil) {
            self.timerForMovingCarousel = NSTimer.scheduledTimerWithTimeInterval(numberOfSecondsBetweenFiringsOfTheTimer,
                                                                            target: self,
                                                                            selector: "moveCarousel",
                                                                            userInfo: nil,
                                                                            repeats: true)
        }
    }

    func moveCarousel() {
        println("I move the carousel.")

        let currentContentViewControllerDisplayed = self.pageViewController!.viewControllers[0] as! ContentViewController

        var index: Int = currentContentViewControllerDisplayed.index

        if index == self.arrayViewControllers.count - 1 {
            index = 0
        } else {
            ++index
        }

        let contentViewControllerToDisplay = self.arrayViewControllers[index] as! ContentViewController

        self.pageViewController.setViewControllers([contentViewControllerToDisplay],
                                                    direction: UIPageViewControllerNavigationDirection.Forward,
                                                    animated: true,
                                                    completion: nil)

        self.pageControl.currentPage = contentViewControllerToDisplay.index
    }

    func invalidateTimerForMovingCarousel() {
        if (self.timerForMovingCarousel != nil) {
            self.timerForMovingCarousel.invalidate()
            self.timerForMovingCarousel = nil
        }
    }

}
Rey Mago
fuente
1
¿Podría darme un ejemplo completo de esto? Porque estoy haciendo algo como esto. Cómo usar esta extensión con mi código. Si lo desea, puedo enviarle el código.
Sábado
2

Sin embargo, el uso de esta llamada al método 'self.pageViewController setViewControllers' no llama a 'viewDidDissapear' en viewController para la página que ha sido rechazada, mientras que al girar manualmente una página llama a viewDidDissapear en la página rechazada. Creo que esta es la causa de mi accidente.

"El número de controladores de vista proporcionados (0) no coincide con el número requerido (1) para la transición solicitada"

noRema
fuente
intente usar: - pageViewController: didFinishAnimating: previousViewControllers: transitionCompleted:
Graham
2

También necesitaba un botón para navegar hacia la izquierda en un PageViewController, uno que debería hacer exactamente lo que esperarías del movimiento de deslizamiento.

Como ya tenía algunas reglas dentro de " pageViewController: viewControllerBeforeViewController " para manejar la navegación de deslizamiento natural, quería que el botón reutilizara todo ese código, y simplemente no podía permitirme usar índices específicos para llegar a las páginas como el anterior las respuestas lo hicieron. Entonces, tuve que tomar una solución alternativa.

Tenga en cuenta que el siguiente código es para un controlador de vista de página que es una propiedad dentro de mi ViewController personalizado y tiene su columna vertebral configurada en la mitad.

Aquí está el código que escribí para mi botón Navegar a la izquierda:

- (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];
    }
}

Puede hacer algo muy similar para hacer un botón de navegación derecho desde aquí.

tuliomir
fuente
2

En caso de que el CONTROL DE PÁGINA indique que la página actual es O&&. Desea que las páginas naveguen mediante desplazamiento y también haciendo clic en los botones personalizados en Page ViewController, a continuación puede ser útil.

//Set Delegate & Data Source for PageView controller [Say in View Did Load]
   self.pageViewController.dataSource = self;
   self.pageViewController.delegate = self;

// Delegates called viewControllerBeforeViewController when User Scroll to previous page 

 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{

    [_nextBtn setTitle:@"Next" forState:UIControlStateNormal];

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

    if (index == NSNotFound){
        return nil;
    }else if (index > 0){
        index--;
    }else{
        return nil;
    }        
    return [self viewControllerAtIndex:index];        
}

// Delegado llamado viewControllerAfterViewController cuando el usuario se desplaza a la página siguiente

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

if (index == NSNotFound){
    return nil;
}else if (index < 3){
    index++;
}else{
    return nil;
}
return [self viewControllerAtIndex:index];}

//Delegate called while transition of pages. The need to apply logic in this delegate is to maintain the index of current page.

 - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers{ 

buttonIndex = (int)((PageContentViewController*) pendingViewControllers.firstObject).pageIndex;

}

-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{    
if (buttonIndex == 0){
    _backButton.hidden = true;
}else if (buttonIndex == [self.pageImages count] - 1){
    _backButton.hidden = false;
    [_nextBtn setTitle:@"Begin" forState:UIControlStateNormal];
}else{
    _backButton.hidden = false;
}

}

// Lógica de botones personalizados (Anterior y siguiente)

-(void)backBtnClicked:(id)sender{
    if (buttonIndex > 0){
buttonIndex -= 1;
    }
    if (buttonIndex < 1) {
        _backButton.hidden = YES;
    }
    if (buttonIndex >=0) {
         [_nextBtn setTitle:@"Next" forState:UIControlStateNormal];
        PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
        NSArray *viewControllers = @[startingViewController];
        [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    }

}

-(void)nextBtnClicked:(id)sender{
if (buttonIndex < 3){
buttonIndex += 1;
}
if(buttonIndex == _pageImages.count){
   //Navigate Outside Pageview controller        
}else{        
    if (buttonIndex ==3) {

        [_nextBtn setTitle:@"Begin" forState:UIControlStateNormal];
    }
    _backButton.hidden = NO;

    PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
    NSArray *viewControllers = @[startingViewController];
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}

}

//BUTTON INDEX & MAX COUNT
-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
    return [self.pageImages count];}

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
    return  buttonIndex;}
Yogesh Lolusare
fuente
Has publicado la misma respuesta casi exacta a cuatro preguntas. Si cree que uno de ellos es un duplicado del otro, debe marcarlos como tales (y no publicar la misma respuesta varias veces).
Jaap
Entonces, ¿puedo publicar el enlace de esta pregunta sobre otra pregunta similar pero la solución es la misma?
Yogesh Lolusare
1
No quiero juzgar ni nada, pero su formato de código me parece muy desagradable.
Lukas Petr
1
Justo @Lukas, lo formatearé ahora mismo. Gracias
Yogesh Lolusare
2
- (void)moveToPage {

    NSUInteger pageIndex = ((ContentViewController *) [self.pageViewController.viewControllers objectAtIndex:0]).pageIndex;

    pageIndex++;

    ContentViewController *viewController = [self viewControllerAtIndex:pageIndex];

if (viewController == nil) {
        return;
    }
    [self.pageViewController setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

}

// ahora llama a este método

[self moveToPage];

Espero que funcione :)

D.Garcia
fuente
1

Para una sola página, acabo de editar la respuesta de @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];
}
Smit Shah
fuente
0

Como señaló @samwize, la forma de paginar es mediante el uso de

setViewControllers:array

Así es como lo hice: tengo mi fuente de datos y el delegado separados. Puede llamar a este método y solo cambiar la vista "siguiente". Previamente debe aplicar las reglas de paginación. Es decir, debe verificar la dirección y el siguiente controlador. Si usa ese método con su fuente de datos personalizada, la matriz de controladores que está mostrando no cambiará (ya que usará una matriz personalizada en una subclase de NSObject).

Usando su propia fuente de datos, el método solo establece una nueva vista (con dirección específica). Ya que aún controlará las páginas que se mostrarán cuando deslice normalmente.

Wolffan
fuente
0

Estoy trabajando en ello desde ayer y finalmente lo hice. No pude usar totalmente la plantilla estándar, porque tengo tres viewControllers diferentes como vistas secundarias:

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

Necesitaba un botón de activación solo en el primer VC, así que agregué una propiedad para pageViewController y modelo:

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

@interface VC1 : UIViewController

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

@end

Reescribí el método init del modelo para pasar el guión gráfico y pageViewController como parámetros, para poder configurarlos en mi 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;
}

Finalmente, agregué una IBAction en mi vc1 para activar el método pageViewController setViewControllers: direction: animated: complete ::

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

Tenga en cuenta que no necesito encontrar índices de VC, mi botón me lleva a mi segundo VC, pero no es difícil obtener todos los índices y realizar un seguimiento de sus vistas secundarias:

- (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];
}

¡Espero que te ayude!

Thomás Calmon
fuente
0

Aquí hay una solución que usa los métodos UIPageViewControllerDataSource :

El código realiza un seguimiento del controlador de vista visualizado actual en el UIPageViewController .

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

Primero inicialice currentViewController en el controlador de vista inicial configurado para UIPageViewController .

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

A continuación, realizar un seguimiento de currentViewController en los UIPageViewControllerDelegate métodos: pageViewController: willTransitionToViewControllers: y pageViewController: didFinishAnimating: previousViewControllers: transitionCompleted: .


- (nullable UIViewController *) pageViewController: (UIPageViewController *) pageViewController viewControllerBeforeViewController: (UIViewController *) viewController {
    NSInteger idx = [self.viewControllers indexOfObject: viewController];
    if (idx > 0) {
        return self.viewControllers[idx - 1];
    } else {
        return nil;
    }
}

- (nullable UIViewController *) pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController: (UIViewController *) viewController {
    NSInteger idx = [self.viewControllers indexOfObject: viewController];
    if (idx == NSNotFound) {
        return nil;
    } else {
        if (idx + 1 < self.viewControllers.count) {
            return self.viewControllers[idx + 1];
        } else {
            return nil;
        }
    }
}

- (void) pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers {
    self.nextViewController = [pendingViewControllers firstObject];
}

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed {
    if (completed) {
        self.currentViewController = self.nextViewController;
    }
}

Por último, en el método de su elección (en el ejemplo siguiente se de - (IBAction) onNext: (id) del remitente ), se puede cambiar mediante programación al controlador anterior o siguiente mediante UIPageViewControllerDataSouce métodos pageViewController: viewControllerBeforeViewController: , pageViewController: viewControllerAfterViewController: para obtener el controlador de vista siguiente o anterior y navegue hasta él llamando a [self.pageViewController setViewControllers: @ [vc] direction: UIPageViewControllerNavigationDirectionForward animated: YES complete: nil];


- (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];
    }
}
pconor
fuente
Una explicación detallada habría sido muy útil.
Taslim Oseni
@TaslimOseni, gracias por señalar que el ejemplo no fue lo suficientemente claro. Agregué una descripción de cómo funciona, avíseme si necesita más explicaciones.
pconor
0

Como los ViewControllers están incrustados en el PageViewController, todo lo que tiene que hacer es:

  • Recupere el controlador de vista principal y eche como su clase relevante.
  • Use esa propiedad de origen de datos de los padres para obtener el siguiente ViewController.
  • Use el método SetParentViewControllers para establecer y pasar a la página siguiente.

Ejemplo en Xamarin, pero funcionalmente similar a Swift, etc. El siguiente código estaría en el delegado Click Button en uno de los ViewControllers que se muestra como una página:

var parent = ParentViewController as WelcomePageViewController;
var next = parent.DataSource.GetNextViewController(parent, this);

parent.SetViewControllers(new UIViewController[] { next }, UIPageViewControllerNavigationDirection.Forward, true, null);
Grant K
fuente