web-dev-qa-db-ja.com

UIPageViewController:currentPageを取得します

私は過去数日間この問題に苦労してきましたが、このジャグリングの後、必要なのは現在の表示ページ番号で更新するためのデータソースメソッドの現在のインデックスだけであることがわかりました

このUIPageViewControllerデータソースメソッドがあり、デリゲートメソッド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;
}

現在の表示ページを更新するために、datasourceメソッドからデリゲートメソッドに現在のインデックスステートメントを書き込む方法について混乱しています。

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

どうすれば修正できますか?

24
user1120133

現在のインデックスを取得できるはずです:

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

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

modelControllerを実装する場合(Apple例)のように、そのメソッドを使用します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

私はpageViewControllerで同じ問題に直面していますが、pageViewControllerをスワイプするたびにデリゲートが2回呼び出され、問題を見つけることができません。そして、私の配列は動的なので、pageControllerから適切なインデックス値が必要です。まず、pageViewControllerのデリゲートを設定します。このような :-

self.pageViewController.delegate = self;

そして、このdelegateメソッドをクラスに追加します

- (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は、pageViewControllerのデータを表示するクラスです。 My PageContentViewController class looks like this

プロジェクトを実行し、すべてが正常に機能している場合、インデックス値を取得します。 PageIndexは、現在のインデックスを取得するための整数値です。それがあなたを助けることを願っています。

ありがとう

マンディープ・シン

4
Mandeep Singh

デリゲートメソッドを実装する

- (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は常に現在表示されているView ViewControllerを返します

4
avinash

この問題は次のように解決しました。

*親View Controller(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

* Child View Controller *

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

たとえば、parentPageViewControllerのcurrentPageIndexは10または他の値です。右にスワイプすると、parentViewController.currentPageIndexは9になり、0の場合は何も起こりません。左にスワイプすると、表示するcontroller.viewが最後の場合、parentPageViewController.currentPageIndexは11になり、何も起こりませんでした。

2
Z.Chris.

私もこれに苦労し、他のソリューションはどれもうまくいきませんでしたが、最終的にデリゲートメソッドを使用して解決することができました:

最初 PageContentViewController.hで次のプロパティを追加します。

@property NSUInteger pageIndex;

Second PageViewViewControllerではなく、PageContentViewControllerにデリゲートプロトコルを作成します。

PageContentViewController.h内:

 @protocol PageContentDelegate <NSObject>

 - (void)sendBackPageIndex:(NSUInteger)index;

@end

@interface LKFPageContentViewController : (UIViewController)

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

Third PageContentViewController.mでviewDidAppearでデリゲートメソッドを実行します

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

[super viewDidAppear:YES];

[self.delegate sendBackPageIndex:self.pageIndex];

第4、PageViewController.mでデリゲートメソッドを実装します

#pragma mark - PageContentView delegate methods

- (void)sendBackPageIndex:(NSUInteger)index {

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

5番目、PageViewController.mでpageIndex値を渡し、デリゲートを設定していることを確認します

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

現在のインデックスを取得するには、次を実行する必要があります。

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

これを試すことができます。これにより、現在のページが表示されます。

    - (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
Shital Zope

これを行う良い方法はありませんが、最も信頼できる方法は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

私のアプローチは非常に簡単です:

  1. ページ(コントローラー)がインスタンス化されると、I ページインデックスを渡すとなります。これはこの時点で既知です。

  2. 次に、以下のデリゲート呼び出しで、遷移が終了した場合、現在表示されているコントローラーを取得し、カスタムページクラスにキャストしてから、関連するページインデックスでcurrentPageを取得して更新します。

物事をシンプルに保つために、データソースとデリゲートをセットアップして、Page View Controllerを埋め込むWalkThroughControllerにします。

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
    }

}

テイクアウェイポイントは、データソースで作成されたページのページインデックスを設定することです。このアプローチでは、後で取得するのは非常に簡単です。

0
Johan

これは、ユーザーが左または右にスワイプするかどうか、およびスワイプの途中でスワイプ方向ジェスチャーを変更するかどうかで、現在のページインデックスを決定する方法です。インデックスを保存するために、View ControllerにpageIndexプロパティがあることを確認してください。

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