web-dev-qa-db-fra.com

UIPageViewController: récupère la currentPage

Je suis aux prises avec ce problème depuis quelques jours et après tout ce jonglage, j'ai réalisé que tout ce dont j'avais besoin était l'index actuel de la méthode de source de données pour mettre à jour le numéro de page visible actuel

J'ai cette méthode UIPageViewController datasource et je dois utiliser l'index actuel pour obtenir la page visible actuelle de la méthode déléguée previousViewControllers transitionCompleted:(BOOL)completed

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
   viewControllerAfterViewController:(UIViewController *)viewController { 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"pages" ofType:@"pdf"];

    NSURL *pdfurl = [NSURL fileURLWithPath:path];
    PDFDocument = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfurl);

    contentViewController = [[ContentViewController alloc] initWithPDFAtPath:path];

    currentIndex = [modelArray indexOfObject:[(ContentViewController *)viewController page]];

    if (currentIndex == totalPages - 1) {  
        return nil;
    }

    contentViewController.page = [modelArray objectAtIndex:currentIndex + 1];

    return contentViewController;
}

Je ne comprends pas comment écrire l'instruction d'index en cours à partir de la méthode datasource en méthode déléguée pour mettre à jour la page visible en cours.

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{

    if (!completed)
    {
        return;
    }

    //currentIndex = [[self.pageViewController.viewController lastObject]];  
    currentIndex = [self indexOfObject:contentViewController];

    [self displaycurrentIndex:currentIndex];
    //self.pageControl.currentPage = currentIndex;
}

Comment puis-je corriger cela?

24
user1120133

Il semble que vous devriez pouvoir obtenir l'index actuel avec:

ContentViewController *viewController = [self.pageViewController.viewControllers lastObject];
currentIndex = [modelArray indexOfObject:[viewController page]];
26
Wain

pour Swift:

func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool){
        let pageContentViewController = pageViewController.viewControllers![0] as! ViewController
        let index = pageContentViewController.pageIndex

}
19
sof98789

si vous implémentez ModelController (comme dans l'exemple Apple), utilisez sa méthode indexOfViewController

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {
    myDataViewController *currentView = [pageViewController.viewControllers objectAtIndex:0];
    NSInteger currentIndex = [_modelController indexOfViewController:currentView];
    [self displayPageNumber:currentIndex];
}
8
djdance

Je suis confronté au même problème sur pageViewController, chaque fois que je glisse mon pageViewController, il appelle mon délégué deux fois et ne peut pas trouver le problème. Et mon tableau est dynamique, donc je veux la valeur d'index appropriée de pageController. Tout d’abord, définissez le délégué de votre pageViewController. Comme ça :- 

self.pageViewController.delegate = self;

Et ajoutez ensuite cette méthode delegate à votre classe

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
if (completed) {
    NSInteger currentIndex = ((PageContentViewController *)self.pageViewController.viewControllers.firstObject).pageIndex;

    NSLog(@"%ld",(long)currentIndex);
}
}

PageContentViewController est la classe dans laquelle vous affichez vos données de pageViewController.  My PageContentViewController class looks like this

Exécutez votre projet et si tout fonctionne correctement, vous obtiendrez votre valeur d'index .PageIndex est la valeur Integer permettant d'obtenir l'index actuel. J'espère que ça vous aidera.

Merci

Mandeep Singh

4
Mandeep Singh

Implémenter la méthode du délégué

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{
        NSLog(@"Current Page = %@", pageViewController.viewControllers);

        UIViewController *currentView = [pageViewController.viewControllers objectAtIndex:0];

             if ([currentView isKindOfClass:[FirstPageViewController class]]) {
                 NSLog(@"First View");
            }
            else if([currentView isKindOfClass:[SecondPageViewController class]]){
                 NSLog(@"Second View");
            }
            else if([currentView isKindOfClass:[ThirdViewController class]]){
                  NSLog(@"Third View");
            }
 }

//pageViewController.viewControllers renvoie toujours la vue actuelle visible ViewController

4
avinash

J'ai résolu ce problème comme ceci:

* Contrôleur de vue parent (PageViewController) *

@interface MyParentPageViewController () <UIPageViewControllerDataSource>


@property (nonatomic, assign) NSUInteger currentPageIndex;

@end

@implementation MyParentPageViewController

- (void)viewDidLoad 
{
  [super viewDidLoad];

  MyChildViewController *rootChildViewController = [MyChildViewController controllerWithPageIndex:self.currentPageIndex];
  [self setViewControllers:@[rootChildViewController]
             direction:UIPageViewControllerNavigationDirectionForward
              animated:YES completion:nil];
  self.dataSource = self;
}

#pragma mark - Page View Controller DataSource
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController 
viewControllerAfterViewController:(MyChildViewController *)viewController
{
  if (viewController.pageIndex == self.sourceArray.count - 1) {
    return nil;
  }
  MyChildViewController *vc = [MyChildViewController controllerWithPageIndex:viewController.pageIndex + 1];
  return vc;
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(CHHomeDetailTableController *)viewController 
{
  if (viewController.pageIndex == 0) {
    return nil;
  }
  MyChilViewController *vc = [MyChildViewController controllerWithPageIndex:viewController.pageIndex - 1];
  return vc;
}


@end

* Contrôleur de vue enfant *

@implementation MyChildViewController
- (void)viewWillAppear
{
    MyParentPageViewController *parentPageViewController = (MyParentPageViewController *)self.parentViewController;
    parentViewController.currentPageIndex = self.pageIndex;
}
@end

Par exemple, currentPageIndex de parentPageViewController est égal à 10, ou à une autre valeur, lorsque vous balayez vers la droite, parentViewController.currentPageIndex sera 9, si 0, rien ne se passe; Si vous faites glisser votre doigt vers la gauche, parentPageViewController.currentPageIndex sera égal à 11, si la vue controller.view est la dernière, rien ne s’est produit. 

2
Z.Chris.

J'ai également eu du mal avec cela et aucune des autres solutions ne fonctionnait pour moi, mais j'ai finalement réussi à le résoudre en utilisant une méthode de délégation:

First dans PageContentViewController.h Ajoutez la propriété suivante:

@property NSUInteger pageIndex;

Deuxièmement créer un protocole de délégué dans PageContentViewController (pas le PageViewController).

Dans PageContentViewController.h:

 @protocol PageContentDelegate <NSObject>

 - (void)sendBackPageIndex:(NSUInteger)index;

@end

@interface LKFPageContentViewController : (UIViewController)

@property (weak, nonatomic) id<LKFPageContentDelegate> delegate;
....
@end

Troisième dans PageContentViewController.m effectuer la méthode déléguée dans viewDidAppear

//Note that this must be done in viewDidAppear not viewDidLoad
- (void)viewDidAppear:(BOOL)animated {

[super viewDidAppear:YES];

[self.delegate sendBackPageIndex:self.pageIndex];

Quatrième , dans PageViewController.m implémenter la méthode delegate

#pragma mark - PageContentView delegate methods

- (void)sendBackPageIndex:(NSUInteger)index {

    //This is where you get your current page index
    NSUInteger currentPageIndex = index;
}

Cinquième , dans PageViewController.m, assurez-vous de transmettre la valeur pageIndex et définissez le délégué

- (PageContentViewController *)viewControllerAtIndex:(NSUInteger)index {

    if (([self.arrayOfTitles count] == 0) || (index >= [self.arrayOfTitles count])) {
        return nil;
    }

    // Create a new view controller and pass suitable data.
    PageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageContentViewController"];

    pageContentViewController.pageIndex = index;

    pageContentViewController.delegate = self;

    return pageContentViewController
}
2
Lisa Bohn

Pour obtenir l'index actuel, vous devez procéder comme suit:

-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {


   NSUInteger index = [self.viewControllers indexOfObject: [pageViewController.viewControllers lastObject]];

   NSLog(@"INDEX: %lu",(unsigned long)index);

}
2
Adam Cooper

Vous pouvez essayer ça. Cela vous donnera la page actuelle.

    - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
    UIViewController * viewController = [previousViewControllers lastObject];

    NSUInteger previousPage = [(PageContentViewController *)viewController index];

    NSUInteger currentPage = previousPage+1;
}
1
Aditya Shinde

Il n'y a pas de bonne façon de faire cela, mais je pense que le moyen le plus fiable est d'observer les appels UIPageViewControllerDelegate:

var index: Int
var proposedViewController: UIViewController?

// MARK: UIPageViewControllerDelegate

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    guard let proposedViewController = proposedViewController,
        let index = myViewControllers?.index(of: proposedViewController) else {
            return
    }
    self.index = index
}

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    guard pendingViewControllers.count == 1,
        let proposedViewController = pendingViewControllers.first else {
        return
    }
    self.proposedViewController = proposedViewController
}
0
Andrew Campoli

Mon approche est assez simple:

  1. Lorsque la page (contrôleur) est instanciée, I passe dans l'index de page , qui est connu à ce stade.

  2. Ensuite, dans l'appel délégué ci-dessous, si la transition est terminée, j'obtiens le contrôleur actuellement affiché et le convertis dans ma classe de page personnalisée, avant d'extraire et de mettre à jour la page en cours avec l'index de page associé.

Pour que les choses restent simples, j'ai configuré la source de données et le délégué comme étant la variable WalkThroughController qui intègre le contrôleur de vue de page.

extension WalkThroughController: UIPageViewControllerDelegate {

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {

        guard finished, let currentPageController = pageViewController.viewControllers?.last as? WalkThroughPageViewController else {
            return
        }

        self.currentPage = currentPageController.pageIndex
    }

}

Le point de départ est de définir l’index des pages lors de leur création dans la source de données. Avec cette approche, il est très simple de le récupérer plus tard.

0
Johan

C’est ainsi que je détermine l’index de la page en cours, que l’utilisateur glisse vers la gauche ou vers la droite et qu’il modifie son geste de direction en cours de glissement. Assurez-vous simplement que vous avez une propriété pageIndex dans votre contrôleur de vue pour stocker l'index:

func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
        let currentPageIndex = (pendingViewControllers.last! as! ViewController).pageIndex!
    }
0
jaytrixz