UIPageViewController:現在表示されているビューを返します


89

内部に表示されている現在のページ/ビューはUIPageViewController何ですか?

viewDidAppear子ビューのメソッドをオーバーライドして、メソッドで親ビューにIDを送信するようにしましたviewDidAppear

しかし、問題はこれです:表示されたページのIDとしてそのIDを確実に使用できません。ユーザーがページをめくったが途中でめくりを停止してページを元に戻すことにした場合、viewDidAppearすでに呼び出されているためです。(ビューはカールしたページの背後に表示されます)。

多分私は現在のビューが消えた場合にのみ新しいIDに切り替える必要があります。しかし、現在表示されているビューを返す簡単な方法はないのでしょうか。


viewDidAppear:animated:代わりに使用してみましたか?
ティル

はい、そうです。私はそれを使いました。間違いを訂正するために質問を編集しました。
1

質問の編集方法は私には意味がありません。そのIDをviewWillAppear内から、またはviewDidAppearから送信します。編集内容を再確認してください。
2011

申し訳ありませんが、質問の編集に失敗しました。私はずっとviewDidAppearを使いました。私の最後の編集でそれが明確になることを願っています。
Jan

ここの人を見てください、これは私のために機能しますstackoverflow.com/a/36860663/4286947
theDC

回答:


103

現在のページを手動で追跡する必要があります。デリゲートメソッドpageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:は、その変数を更新するタイミングを通知します。メソッドの最後の引数は、transitionCompleted:ユーザーがページめくりの遷移を完了したかどうかを示します。


1
正解の+1-UIPageViewControllerを使用してiOS5のみをサポートする機会があったらいいのにと思います。
ティル

ありがとう、それはまさに私が探していたクリーンなソリューションです。ページの代理人よりも優れています。
Jan

3
デバイスを回転させるとき、どのように現在のページを追跡しますか?
Satyam、2012

できる限り、プロジェクトの最小バージョンをios5.0に設定してください
mtmurdock

83
現在のページ番号をインクリメントするかデクリメントするかはどのようにしてわかりますか?
シム2014

59

iOS 6の時点でviewControllers、UIPageViewController のプロパティは常に更新されるため、現在のページを表す1つのビューコントローラーだけを保持し、それ以外は何も保持しないことがわかりました。したがって、呼び出しによって現在のページにアクセスできますviewControllers[0](一度に1つのView Controllerのみを表示するとします)。

viewController配列は、ページが「ロック」されたときにのみ更新されるため、ユーザーが次のページを部分的に表示することを決定した場合、移行を完了しない限り、「現在の」ページにはなりません。

「ページ番号」を追跡したい場合は、UIPageViewControllerデータソースメソッドを使用して作成するときに、ビューコントローラーにインデックス値を割り当てます。


だから例えば:

-(void)autoAdvance
    {
    UIViewController *currentVC = self.viewControllers[0];
    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];

    if ( currentIndex >= (myViewControllers.count-1) ) return;

    [self setViewControllers:@[myViewControllers[ currentIndex+1 ]]
        direction:UIPageViewControllerNavigationDirectionForward
        animated:YES
        completion:nil];
    }
-(NSInteger)presentationIndexForPageViewController:
                         (UIPageViewController *)pageViewController
    {
    // return 0;
    UIViewController *currentVC = self.viewControllers[0];
    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];
    return currentIndex;
    }

しかし、これは信頼できないというコメントに注意してください


2
信頼できないことがわかりました。問題の原因を見つけることができませんでした。アニメーションが終了すると、viewControllersプロパティにアクセスしspineLocationForInterfaceOrientationて適切なビューコントローラーを取得しますが、メソッドで回転すると、正しいビューコントローラーを取得できなくなります。そのため、常にに依存するのではなく、独自のcurrentPageプロパティを維持することに固執しましたviewControllers
ファビオ・オリベイラ

興味深いことに、私は少し遊んで、これらの特別なケースでどのように動作するかを確認します
Eddy Borja

2
また、信頼性が低いことがわかりました。AppleはページめくりごとにviewControllerBeforeViewControllerまたはviewControllerAfterViewControllerを呼び出すだけですが、UIPageViewController.viewControllersは更新しません。私は彼らがこれらのタイプのことを間違ってするためにどうやって管理し続けるのか分かりませんが、彼らはそうします。それは本当に私のワークロードを上げ、そして私のコードの明快さを壊します(しばしばDRYと他の原則に違反しています)。
ザックモリス

3
@ZackMorris。それは絶対に素晴らしいです、あなたは全く正しいです。それは「アップルの恐怖の瞬間」です。なぜそうなのか、1つ右に移動する、現在どのページにいるのかなどの明らかな機能が含まれていないのはなぜでしょうか。
Fattie

1
self.viewControllers [0]は私には問題なく動作するようです。ただし、開始時にsetViewControllersを1回だけ呼び出し、残りは自動化に任せました。(iOS 8.4でテスト済み)
ボブ

45

残念ながら、上記のすべての方法は私を助けませんでした。それにもかかわらず、私はタグを使用して解決策を見つけました。それは最善ではないかもしれませんが、それは機能し、誰かを助けることを願っています:

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed 
{
    if (completed) {
        int currentIndex = ((UIViewController *)self.pageViewController.viewControllers.firstObject).view.tag;
        self.pageControl.currentPage = currentIndex;
    }
}

Swift:@Jessyに感謝)

func pageViewController(pageViewController: UIPageViewController,
    didFinishAnimating finished: Bool,
    previousViewControllers: [UIViewController],
    transitionCompleted completed: Bool)
{
    guard completed else { return }
    self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
}

例: 要旨


3
これは最も簡単で、私にとってはうまくいきました。ビューコントローラーの追加時にタグを設定します(例:HelpPage1ViewController * page1 = [self.storyboard instantiateViewControllerWithIdentifier:@ "page1"]; page1.view.tag = 0;)。次に、現在の場所を追跡するために、マスタービューコントローラーのcurrentPageプロパティを設定できます。データソースだけでなく、両方のプロトコル( "<UIPageViewControllerDataSource、UIPageViewControllerDelegate>")を追加し、デリゲートをself( "self.pageViewController.delegate = self;")に設定しないと、メソッドが呼び出されません。これは私を少し困惑させました。
James Toomey 2014年

1
@VictorMこのソリューションは私には機能しません。異なる画像のpageViewControllerがあります。スワイプごとにタグ0を返し続けますが、なぜこれが発生するのでしょうか?事前の感謝
theDC

1
@VictorM私は数日かけてインデックスを保存しようとしましたが、誤ってこの答えを見つけました、1000回賛成できればいいのですが、ありがとうございます!
Evgeniy Kleban 2017年

1
素晴らしい解決策これを回避するために何時間も費やしてくれたおかげで
ビジョンムハベラ2017年

値0のみを返します

35

オレの答えに基づいて…

これは、現在のページを追跡し、ページインジケーターを正しいインデックスに更新する4つのメソッドを実装した方法です。

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{

    return (NSInteger)[self.model count];

}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{

    return (NSInteger)self.currentIndex;
}

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

    SJJeanViewController* controller = [pendingViewControllers firstObject];
    self.nextIndex = [self indexOfViewController:controller];

}

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

    if(completed){

        self.currentIndex = self.nextIndex;

    }

    self.nextIndex = 0;

}

2
トランジションが完了していないときにインデックスを適切に復元するためでself.nextIndex = self.currentIndexはなく、最後の行にする必要があると思いますself.nextIndex = 0。そうしないcurrentIndexと、ページの途中のどこかでページングをすばやく行ったり来たりしたときに、値が0になるというリスクがあります。
hverlind 2014

1
これでは十分に機能しません。ときどき、pageViewController:willTransitionToViewControllersが呼び出されず、nextIndexが変更されず、現在のインデックスが間違っていることがあります。
ヘイデンホリガン2015年

31

以下の解決策は私のために働いた。

Appleは、ネイティブのUIPageViewControllerスクロールビューのページ分割をより構成可能にすることで、多くの手間を回避できました。ネイティブUIPageViewControllerのページネーションが透明な背景やビューフレーム内の再配置をサポートしていないという理由だけで、新しいUIViewとUIPageControlをオーバーレイする必要がありました。

- (void)pageViewController:(UIPageViewController *)pvc didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
  if (!completed)
  {
    return;
  }
  NSUInteger currentIndex = [[self.pageViewController.viewControllers lastObject] index];
  self.pageControl.currentPage = currentIndex;
}

1
これで、インデックスとはどういう意味ですか?
ヨハン14

インデックス(つまり、self.pageViewController.viewControllersの配列内の現在のビューコントローラーの位置を表す整数)を取得し、それを使用してself.pageControlのcurrentPage属性を設定します(整数値が必要です)。 。理にかなっていますか?
サーバイン2014

6
インデックスは、私は信じてここにカスタムプロパティである
アダム・ジョーンズ

この問題は、アニメーションメソッドなしでページを変更したい場合に呼び出されないことです
Silviu St

19

スウィフト4

不要なコードはありません。それを行う3つの方法。UIPageViewControllerDelegateメソッドを使用します。

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

    // using content viewcontroller's index
    guard let index = (pageViewController.viewControllers?.first as? ContentViewController)?.index else { return }

    // using viewcontroller's view tag
    guard let index = pageViewController.viewControllers?.first?.view.tag else { return }

    // switch on viewcontroller
    guard let vc = pageViewController.viewControllers?.first else { return }
    let index: Int
    switch vc {
    case is FirstViewController:
        index = 0
    case is SecondViewController:
        index = 1
    default:
        index = 2
    }
}

ああ、助かった!知りませんでしたpageViewController.viewControllers。どのようにしてviewControllersを知っていますか?.firstは問題の1つですか?
スクリプトキティ

かなり単純ですが、viewControllers配列には、現在表示されているビューコントローラのみが含まれています。
Nikola Milicevic

2
その関数からインデックス変数にアクセスするにはどうすればよいですか?
N. Der

11

小さな関数を使用し、静的なNSIntegerとしてpageIndexを指定することにより、ページインデックスを追跡しています。

-(void) setPageIndex
{
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];

    pageIndex = [self.modelController indexOfViewController:theCurrentViewController];
}

[self setPageIndex];Oleによって指定された関数内で、また方向の変化を検出した後に呼び出します。


5

私は最初にCoreyのソリューションを使用しましたが、iOS5では機能しなかったため、結局使用しました。

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

    if(completed) {
        _currentViewController = [pageViewController.viewControllers lastObject];
    }
}

別のページに切り替えてみましたが、今のところうまくいきます。


3

残念ながら、上記では何もうまくいきません。

私には2つのビューコントローラーがあり、最後のビューを少し(約20px)後方にスクロールすると、デリゲートがトリガーされます。

pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:

そして、現在のページ(インデックス)は0どちらが間違っていると言っています。

子viewController内でデリゲートを使用すると、次のようになります。

- (void)ViewController:(id)VC didShowWithIndex:(long)page;

// and a property

@property (nonatomic) NSInteger index;

それは内部でトリガーされviewDidAppearます:

- (void)viewDidAppear:(BOOL)animated
{
    ...

    [self.delegate ViewController:self didShowWithIndex:self.index];
}

私のために働いた。


3

これは確実に機能します

カスタムUIPageControllerがあります。このpageController.currentPageは、viewWillAppearに表示されたUIViewControllerから更新されます。

   var delegate: PageViewControllerUpdateCurrentPageNumberDelegate?

      init(delegate: PageViewControllerUpdateCurrentPageNumberDelegate ){
        self.delegate = delegate
        super.init(nibName: nil, bundle: nil)
      }

      required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
      }

    override func viewWillAppear(animated: Bool) {

        if delegate != nil {
          self.delegate!.upateCurrentPageNumber(0) //(0) is the pageNumber corresponding to the displayed controller
        }
      } 

    //In the pageViewController 

    protocol PageViewControllerUpdateCurrentPageNumberDelegate {

      func upateCurrentPageNumber(currentPageIndex: Int)
    }

     create the view display controllers initializing with the delegate

    orderedViewControllers = {
              return [
                IntroductionFirstPageViewController(delegate: self),
                IntroductionSecondPageViewController(delegate: self),
                IntroductionThirdPageViewController(delegate: self)
              ]

            }()

    the function implementing the protocol

    func upateCurrentPageNumber(currentPageIndex: Int){
        pageControl.currentPage = currentPageIndex
      }

1

私はview.tagしばらく使用していますが、現在のページを追跡するのは非常に複雑です。

このコードでは、インデックスはtagそれぞれのプロパティ内に格納されview、次または前のVCをフェッチするために使用されます。この方法を使用すると、無限スクロールを作成することもできます。このソリューションも表示するには、コード内のコメントを確認してください。

extension MyPageViewController: UIPageViewControllerDataSource {

  func viewControllerWithIndex(var index: Int) -> UIViewController! {
    let myViewController = storyboard?.instantiateViewControllerWithIdentifier("MyViewController") as MyViewController

    if let endIndex = records?.endIndex {
      if index < 0 || index >= endIndex { return nil }
      // Instead, We can normalize the index to be cyclical to create infinite scrolling
      // if index < 0 { index += endIndex }
      // index %= endIndex
    }

    myViewController.view.tag = index
    myViewController.record = records?[index]

    return myViewController
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    let index = viewController.view?.tag ?? 0
    return viewControllerWithIndex(index + 1)
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    let index = viewController.view?.tag ?? 0
    return viewControllerWithIndex(index - 1)
  }

  func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
    return records?.count ?? 0
  }

  func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
    return (pageViewController.viewControllers.first as? UIViewController)?.view.tag ?? 0
  }
}

1

回答ありがとうございます、私は同様の問題に直面し、インデックスを保存する必要がありました。コードを少し変更して、下に貼り付けます。

- (MenuListViewController *)viewControllerAtIndex:(NSInteger)index {

    if (_menues.count < 1)
        return nil;

    //    MenuListViewController *childViewController = [MenuListViewController initWithSecondSetFakeItems];
    MenuListViewController *childViewController = self.menues[index];
    childViewController.index = index;

    return childViewController;
}

#pragma mark - Page View Controller Data Source

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

    if (completed) {

        NSUInteger currentIndex = ((MenuListViewController *)self.pageController.viewControllers.firstObject).index;
        NSLog(@"index %lu", (unsigned long)currentIndex);
    }
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [(MenuListViewController *)viewController index];

    if (index == 0)
        return nil;

    index --;

    return [self viewControllerAtIndex:index];
}


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

    NSUInteger index = [(MenuListViewController *)viewController index];

    index ++;

    if (index == _menues.count)
        return nil;

    return [self viewControllerAtIndex:index];
}

0
- (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 always return current visible View ViewController

0

以下のデモコード(Swift 2内)は、簡単な画像スワイパーチュートリアルを実装することによってこれがどのように行われるかを示しています。コード自体のコメント:

import UIKit

/*
VCTutorialImagePage represents one page show inside the UIPageViewController.
You should create this page in your interfacebuilder file:
- create a new view controller
- set its class to VCTutorialImagePage
- sets its storyboard identifier to "VCTutorialImagePage" (needed for the loadView function)
- put an imageView on it and set the contraints (I guess to top/bottom/left/right all to zero from the superview)
- connect it to the "imageView" outlet
*/

class VCTutorialImagePage : UIViewController {
    //image to display, configure this in interface builder
    @IBOutlet weak var imageView: UIImageView!
    //index of this page
    var pageIndex : Int = 0

    //loads a new view via the storyboard identifier
    static func loadView(pageIndex : Int, image : UIImage) -> VCTutorialImagePage {
        let storyboard = UIStoryboard(name: storyBoardHome, bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("VCTutorialImagePage") as! VCTutorialImagePage
        vc.imageView.image      = image
        vc.pageIndex            = pageIndex
        return vc
    }
}


/*
VCTutorialImageSwiper takes an array of images (= its model) and displays a UIPageViewController 
where each page is a VCTutorialImagePage that displays an image. It lets you swipe throught the 
images and will do a round-robbin : when you swipe past the last image it will jump back to the 
first one (and the other way arround).

In this process, it keeps track of the current displayed page index
*/

class VCTutorialImageSwiper: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    //our model = images we are showing
    let tutorialImages : [UIImage] = [UIImage(named: "image1")!, UIImage(named: "image2")!,UIImage(named: "image3")!,UIImage(named: "image4")!]
    //page currently being viewed
    private var currentPageIndex : Int = 0 {
        didSet {
            currentPageIndex=cap(currentPageIndex)
        }
    }
    //next page index, temp var for keeping track of the current page
    private var nextPageIndex : Int = 0


    //Mark: - life cylce


    override func viewDidLoad() {
        super.viewDidLoad()
        //setup page vc
        dataSource=self
        delegate=self
        setViewControllers([pageForindex(0)!], direction: .Forward, animated: false, completion: nil)
    }


    //Mark: - helper functions

    func cap(pageIndex : Int) -> Int{
        if pageIndex > (tutorialImages.count - 1) {
            return 0
        }
        if pageIndex < 0 {
            return (tutorialImages.count - 1)
        }
        return pageIndex
    }

    func carrouselJump() {
        currentPageIndex++
        setViewControllers([self.pageForindex(currentPageIndex)!], direction: .Forward, animated: true, completion: nil)
    }

    func pageForindex(pageIndex : Int) -> UIViewController? {
        guard (pageIndex < tutorialImages.count) && (pageIndex>=0) else { return nil }
        return VCTutorialImagePage.loadView(pageIndex, image: tutorialImages[pageIndex])
    }

    func indexForPage(vc : UIViewController) -> Int {
        guard let vc = vc as? VCTutorialImagePage else {
            preconditionFailure("VCPagImageSlidesTutorial page is not a VCTutorialImagePage")
        }
        return vc.pageIndex
    }


    //Mark: - UIPageView delegate/datasource


    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        return pageForindex(cap(indexForPage(viewController)+1))
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        return pageForindex(cap(indexForPage(viewController)-1))
    }

    func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
        nextPageIndex = indexForPage(pendingViewControllers.first!)
    }

    func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if !finished { return }
        currentPageIndex = nextPageIndex
    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
        return tutorialImages.count
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
        return currentPageIndex
    }

}

0

UIPageViewControllerに表示するviewControllers配列があります

extension MyViewController: UIPageViewControllerDataSource {

func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return self.viewControllers.count
}

func presentationIndex(for pageViewController: UIPageViewController) -> Int {
    return self.currentPageIndex
}
}




extension MyViewController: UIPageViewControllerDelegate {

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

    if !completed { return }

    guard let viewController = previousViewControllers.last, let index = indexOf(viewController: viewController) else {
        return
    }

    self.currentPageIndex = index

}

fileprivate func indexOf(viewController: UIViewController) -> Int? {
    let index = self.viewControllers.index(of: viewController)
    return index
}
}

ここで注意すべき重要な点は、UIPageViewControllerのsetViewControllersメソッドがデリゲートコールバックを提供しないことです。デリゲートコールバックは、UIPageViewControllerのユーザータッチアクションのみを表します。


0

これは私が思いついた解決策です:

class DefaultUIPageViewControllerDelegate: NSObject, UIPageViewControllerDelegate {

    // MARK: Public values
    var didTransitionToViewControllerCallback: ((UIViewController) -> Void)?

    // MARK: Private values
    private var viewControllerToTransitionTo: UIViewController!

    // MARK: Methods
    func pageViewController(
        _ pageViewController: UIPageViewController,
        willTransitionTo pendingViewControllers: [UIViewController]
    ) {
        viewControllerToTransitionTo = pendingViewControllers.last!
    }

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

使用法:

 let pageViewController = UIPageViewController()
 let delegate = DefaultUIPageViewControllerDelegate()

 delegate.didTransitionToViewControllerCallback = {
    pageViewController.title = $0.title
 }

 pageViewController.title = viewControllers.first?.title
 pageViewController.delegate = delegate

最初のタイトルを設定してください


0

このIMHOにアプローチする最も簡単な方法は、PageControlを使用して遷移の潜在的な結果を保存し、遷移がキャンセルされた場合に元に戻すことです。これは、ユーザーがスワイプを開始するとすぐにページコントロールが変更されることを意味します。これには、UIViewControllersの独自の配列が必要です(この例ではと呼ばれますallViewControllers)。

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    if let index = self.allViewControllers.index(of: pendingViewControllers[0]) {
        self.pageControl.currentPage = index
    }
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if !completed, let previousIndex = self.allViewControllers.index(of: previousViewControllers[0]) {
        self.pageControl.currentPage = previousIndex
    }
}

0

(Swift 4バージョン)viewControllerから直接を要求するのはどうですか?UIPageViewController

fileprivate weak var currentlyPresentedVC: UIViewController?

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    currentlyPresentedVC = pageViewController.viewControllers?.first
}

または、ある時点で現在表示されているView Controllerが必要なだけの場合は、その時点で使用pageViewController.viewControllers?.firstします。


0

Swift 5以降のサーバインの回答

extension InnerDetailViewController: UIPageViewControllerDelegate {

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

        if completed {
            guard let newIndex = embeddedViewControllers.firstIndex(where: { $0 == pageViewController.viewControllers?.last }) else { return }
            print(newIndex)
            currentEmbeddedViewControllerIndex = newIndex
        }

    }

} 

この場合、UIViewControllerのどのクラスが埋め込まれているかは気にしません


-1
UIViewController *viewController = [pageViewController.viewControllers objectAtIndex:0];
NSUInteger currentIndex = [(ViewController*) viewController indexNumber];

現在のページインデックスを返します。また、UIPageViewController(didFinishAnimating)のデリゲート関数の下でこのコードを使用する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.