È possibile girare la pagina a livello di codice in UIPageViewController?


Risposte:


235

Sì, è possibile con il metodo:

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

Questo è lo stesso metodo utilizzato per impostare il controller della prima vista sulla pagina. Simile, puoi usarlo per andare ad altre pagine.

Ti chiedi perché viewControllersè un array e non un controller a vista singola?

Questo perché un controller di visualizzazione di pagina potrebbe avere un "dorso" (come in iBooks), che visualizza 2 pagine di contenuto alla volta. Se visualizzi 1 pagina di contenuto alla volta, passa semplicemente in un array di 1 elemento.

Un esempio in Swift:

pageContainer.setViewControllers([displayThisViewController], direction: .Forward, animated: true, completion: nil)

2
Ora che l'NDA è attivo, questo può essere ampliato un po 'di più? Forse un esempio di codice.
SpaceTrucker

11
Penso di averlo finalmente capito: UIPageViewController non si interessa davvero di quale pagina è attualmente. Quando chiami setViewControllers può far sembrare che ti stai allontanando animatamente dal controller di vista corrente, ma non sta davvero cercando una pagina.
Amy,

3
esempio: [self setViewControllers: @ [vcToMoveTo] direction: UIPageViewControllerNavigationDirectionForward animato: YES completamento: zero]; // dove vcToMoveTo è un UIViewController
finneycanhelp

1
Se si desidera continuare a utilizzare UIPageControl, è possibile che si desideri: l'indice self.currentIndex = viewControllerToMoveTo quindi per la presentazioneIndexForPageViewController restituire self.currentIndex
brendan

3
Controllare stackoverflow.com/questions/22554877/… se è necessario aggiornare anche la visualizzazione dell'indicatore di pagina
Protongun

37

Dal momento che avevo bisogno anche di questo, andrò più in dettaglio su come farlo.

Nota: suppongo che tu abbia usato il modulo modello standard per generare la tua UIPageViewControllerstruttura - che ha sia il modelViewControllerche il dataViewControllercreato quando lo invochi. Se non capisci cosa ho scritto, torna indietro e crea un nuovo progetto che usa UIPageViewControllercome base. Capirai allora.

Quindi, la necessità di passare a una determinata pagina implica l'impostazione dei vari pezzi del metodo sopra elencato. Per questo esercizio, suppongo che sia una vista orizzontale con due viste che mostrano. Inoltre, l'ho implementato come IBAction in modo che potesse essere fatto premendo un pulsante o cosa no - è altrettanto facile farlo chiamare selettore e passare gli elementi necessari.

Pertanto, per questo esempio sono necessari i due controller di visualizzazione che verranno visualizzati e, facoltativamente, se si procede in avanti nel libro o all'indietro.

Nota che ho semplicemente programmato dove andare alle pagine 4 e 5 e usare una scheda di sicurezza. Da qui puoi vedere che tutto ciò che devi fare è passare le variabili che ti aiuteranno a ottenere questi elementi ...

-(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!  

}

2
Ho lo stesso requisito per passare a una pagina specifica. Ma il codice sopra non sembra funzionare per me. Che cosa sto facendo di sbagliato? Ho 19 pagine.
Ganesh,

È possibile utilizzare questo frammento di codice anche quando si forniscono i controller di visualizzazione tramite un oggetto origine dati?
Jens Kohl,

20
Che classe bizzarramente mal implementata, Apple.
devios1

29

Ecco un altro esempio di codice per una singola vista paginata. L'implementazione per viewControllerAtIndex è omessa qui, dovrebbe restituire il controller di visualizzazione corretto per l'indice dato.

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

Le pagine possono essere modificate chiamando

[self changePage:UIPageViewControllerNavigationDirectionReverse];
[self changePage:UIPageViewControllerNavigationDirectionForward];

Ma il controllo dell'indice di pagina non viene aggiornato. Come lo faccio?
thatzprem,

1
Questa risposta funziona per me - nota comunque che se fai affidamento sui metodi delegati "didFinishAnimating" di UIPageViewController, non verranno attivati. Invece, sposta il codice da didFinishAnimating a un metodo separato e chiama quel metodo dal blocco di completamento sul metodo setViewControllers.
DiscDev

1
@thatzprem Se vuoi continuare a usare UIPageControl, allora potresti voler: self.currentIndex = viewControllerToMoveTo indice quindi per presentazioneIndexForPageViewController restituire self.currentIndex
brendan

@thatzprem ha ragione. Ogni volta che andrà alla stessa pagina, ad esempio se abbiamo 3 pagine, ogni volta andrà solo alla seconda pagina.
Tushar Lathiya,

18

Potrei davvero mancare qualcosa qui, ma questa soluzione sembra molto più semplice di quanto molti altri abbiano proposto.

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)
            }
        }
    }
}

1
Funziona alla grande! Devo solo cambiare l'indicatore della pagina in qualche modo.
TruMan1

Davvero utile! Per favore, dacci una funzione anche per goToFirstPage.
Mamta,

Ogni volta che andrà alla stessa pagina, ad esempio se abbiamo 3 pagine, ogni volta andrà solo alla seconda pagina.
Tushar Lathiya,

15

Questo codice ha funzionato bene per me, grazie.

Questo è quello che ho fatto con esso. Alcuni metodi per andare avanti o indietro e uno per andare direttamente a una determinata pagina. È per un documento di 6 pagine in vista verticale. Funzionerà bene se lo incolli nell'implementazione del RootController del modello 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];

    }

}

voglio usarlo per la modalità orizzontale in cui esistono due pagine. come usarlo lì. puoi per favore guidare.
iPhone programmaticamente il

9

Swift 4:

Avevo bisogno di andare al controller successivo quando toccavo il successivo su un controller di visualizzazione pagecontroller e anche aggiornare l'indice pageControl, quindi questa è stata la soluzione migliore e più semplice per me :

let pageController = self.parent as! PageViewController

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

pageController.pageControl.currentPage = 1

5

Che dire dell'utilizzo dei metodi da dataSource?

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

Analogamente per tornare indietro.


3

In 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
        }
    }

}

1
Potresti darmi un esempio completo per questo. Perché sto facendo qualcosa del genere. Come usare questa estensione con il mio codice. Se lo desideri, posso inviarti il ​​codice.
Saty,

2

Tuttavia, usando questa chiamata al metodo 'self.pageViewController setViewControllers' non si chiama 'viewDidDissapear' sul viewController per la pagina che è stata girata, mentre girando manualmente una pagina si chiama viewDidDissapear sulla pagina girata. Credo che questa sia la causa del mio incidente

"Il numero di controller di visualizzazione forniti (0) non corrisponde al numero richiesto (1) per la transizione richiesta"


prova a usare: - pageViewController: didFinishAnimating: previousViewController: transizioneCompletato:
Graham

2

Avevo anche bisogno di un pulsante per navigare a sinistra su PageViewController, uno che dovrebbe fare esattamente quello che ti aspetteresti dal movimento del colpo.

Dato che avevo già adottato alcune regole all'interno di " pageViewController: viewControllerBeforeViewController " per gestire la navigazione a scorrimento naturale, volevo che il pulsante riutilizzasse tutto quel codice e semplicemente non potevo permettermi di utilizzare indici specifici per raggiungere le pagine come le precedenti le risposte hanno fatto. Quindi, ho dovuto prendere una soluzione alternativa.

Si noti che il codice seguente è per un Page View Controller che è una proprietà all'interno del mio ViewController personalizzato e che ha il dorso impostato a metà.

Ecco il codice che ho scritto per il mio pulsante Naviga a sinistra:

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

Puoi fare qualcosa di molto simile per creare un pulsante di navigazione corretto da qui.


2

Nel caso in cui CONTROLLO PAGINA per indicare la pagina corrente sia O && Si desidera che le pagine navighino tramite scorrimento e anche facendo clic sui pulsanti personalizzati in Page ViewController, di seguito potrebbe essere utile.

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

// Delegato chiamato viewControllerAfterViewController quando Utente Scorrere alla pagina successiva

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

}

// Logica dei pulsanti personalizzati (precedente e successiva)

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

Hai pubblicato la stessa risposta quasi esatta a quattro domande. Se pensi che uno di essi sia un duplicato dell'altro, dovresti contrassegnarli come tali (e non pubblicare più volte la stessa risposta).
Jaap,

Quindi posso pubblicare il link di questa domanda su un'altra domanda simile ma la soluzione è la stessa.
Yogesh Lolusare,

1
Non intendo giudicare o altro, ma la formattazione del codice mi sembra molto scoraggiante.
Lukas Petr

1
Proprio @Lukas, lo formatterò ora. Grazie
Yogesh Lolusare l'

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

}

// ora chiama questo metodo

[self moveToPage];

Spero che funzioni :)


1

Per singola pagina, ho appena modificato la risposta di @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];
}

0

Come ha sottolineato @samwize, il modo di impaginare è usando

setViewControllers:array

Ecco come l'ho fatto: ho separato l'origine dati e il delegato. È possibile chiamare questo metodo e modificare solo la vista "successiva". In precedenza è necessario applicare le regole di paging. Cioè, devi controllare la direzione e il controller successivo. Se usi questo metodo con l'origine dati personalizzata, l'array di controller che stai visualizzando non cambierà (poiché utilizzerai un array personalizzato su una sottoclasse NSObject).

Utilizzando la propria fonte di dati il ​​metodo imposta semplicemente una nuova vista (con direzione specifica). Dal momento che continuerai a controllare le pagine che verranno visualizzate durante lo scorrimento normale.


0

Ci sto lavorando da ieri e alla fine l'ho fatto funzionare. Non ho potuto utilizzare totalmente il modello standard, perché ho tre differenti viewController come visualizzazioni figlio:

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

Avevo bisogno di un pulsante di attivazione solo nel primo VC, quindi ho aggiunto una proprietà per pageViewController e il modello:

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

@interface VC1 : UIViewController

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

@end

Ho riscritto il metodo init del modello per passare storyboard e pageViewController come parametri, in modo da poterli impostare sul mio 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;
}

Infine, ho aggiunto un IBAction nel mio vc1 per attivare il metodo pageViewController setViewController: direction: animato: completamento ::

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

Nota Non ho bisogno di trovare gli indici VC, il mio pulsante mi porta al mio secondo VC, ma non è difficile ottenere tutti gli indici e tenere traccia delle visualizzazioni dei bambini:

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

Spero che ti aiuti!


0

Ecco una soluzione che utilizza i metodi UIPageViewControllerDataSource :

Il codice tiene traccia dell'attuale controller di visualizzazione visualizzato in UIPageViewController .

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

Inizializzare innanzitutto currentViewController sul set di controller della vista iniziale per UIPageViewController .

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

Poi tenere traccia delle currentViewController nei UIPageViewControllerDelegate metodi: pageViewController: willTransitionToViewControllers: e 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;
    }
}

Infine, nel metodo di vostra scelta (nell'esempio qui sotto è di - (IBAction) onNext: (id) del mittente ), di programmazione è possibile passare al controllo successivo o precedente utilizzando UIPageViewControllerDataSouce metodi pageViewController: viewControllerBeforeViewController: , pageViewController: viewControllerAfterViewController: per ottenere il controller della vista precedente o successivo e accedervi chiamando [self.pageViewController setViewControllers: @ [vc] direzione: UIPageViewControllerNavigationDirectionForward animato: SÌ completamento: zero];


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

Una spiegazione dettagliata sarebbe stata molto utile.
Taslim Oseni,

@TaslimOseni grazie per aver sottolineato che l'esempio non era abbastanza chiaro. Ho aggiunto la descrizione di come funziona, per favore fatemi sapere se necessita di ulteriori spiegazioni.
pconor,

0

Poiché i ViewController sono integrati nel PageViewController, tutto ciò che devi fare è:

  • Recupera il controller della vista padre e trasmetti come classe pertinente.
  • Utilizzare la proprietà dell'origine dati parent per ottenere il ViewController successivo.
  • Utilizzare il metodo SetParentViewControllers per impostare e passare alla pagina successiva.

Esempio in Xamarin, ma funzionalmente simile a Swift ecc. Il seguente codice sarebbe in Button Click delegate in uno dei ViewController mostrato in una pagina:

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

parent.SetViewControllers(new UIViewController[] { next }, UIPageViewControllerNavigationDirection.Forward, true, null);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.