UIPageViewControllerでプログラムによってページをめくることは可能ですか?


回答:


235

はい、それはメソッドで可能です:

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

これは、ページの最初のビューコントローラーを設定するために使用される方法と同じです。同様に、それを使用して他のページに移動できます。

なぜviewControllers単一のビューコントローラーではなく配列なのでしょうか?

これは、ページビューコントローラに「背表紙」(iBooksのような)があり、一度に2ページのコンテンツを表示できるためです。一度に1ページのコンテンツを表示する場合は、1要素の配列を渡します。

Swiftの例:

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

2
NDAが稼働したので、これをもう少し拡張できますか?多分コードサンプル。
SpaceTrucker

11
私はこれを最後に理解したと思います。UIPageViewControllerは、現在どのページにいるかを気にしません。setViewControllersを呼び出すと、現在のビューコントローラから離れてアニメーションで移動しているように見えますが、実際にはページをシークしていません。
2014

3
例:[self setViewControllers:@ [vcToMoveTo] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; // vcToMoveToはUIViewControllerです
finneycanhelp

1
presentationIndexForPageViewControllerリターンself.currentIndexため、その後self.currentIndex = viewControllerToMoveToのインデックス:あなたはUIPageControlを引き続き使用したい場合は、したいこと
ブレンダン・

3
ページインジケーターの表示も更新する必要がある場合は、stackoverflow.com
questions / 22554877 /…を

37

これも必要だったので、これを行う方法についてさらに詳しく説明します。

注:私はあなたが生成するための標準的なテンプレートフォーム使用を前提とUIPageViewController-の両方持っている構造をmodelViewControllerしてdataViewController、あなたがそれを呼び出すときに作成します。私が書いた内容が理解できない場合は、戻って、をUIPageViewController基礎として使用する新しいプロジェクトを作成してください。あなたはその時理解するでしょう。

したがって、特定のページに切り替える必要がある場合は、上記の方法のさまざまな部分を設定する必要があります。この演習では、2つのビューが表示される風景ビューであると想定しています。 また、これをIBActionとして実装したので、ボタンを押すなどの操作から実行できます。セレクターを呼び出して必要な項目を渡すのも同じくらい簡単です。

したがって、この例では、表示される2つのビューコントローラが必要です。また、必要に応じて、本を前に進むか後ろに進むかに関係なく、

4と5ページに移動する場所をハードコーディングし、転送スリップを使用しただけであることに注意してください。ここから、これらの項目を取得するのに役立つ変数を渡すだけでよいことがわかります...

-(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
特定のページに移動するのと同じ要件があります。しかし、上記のコードは私にはうまくいかないようです。何が悪いのですか?19ページあります。
GaneshT

データソースオブジェクトを介してビューコントローラーを提供するときにも、このコードスニペットを使用できますか?
イェンス・コールズ

20
なんと奇妙に実装が不十分なクラス、アップル。
devios1 2014年

29

次に、単一ページビューの別のコード例を示します。ここでは、viewControllerAtIndexの実装は省略されています。指定されたインデックスの正しいView Controllerを返す必要があります。

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

呼び出してページを変更できます

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

ただし、ページインデックスコントロールは更新されません。それ、どうやったら出来るの?
thatzprem 2014年

1
この答えは私にとって有効です-ただし、UIPageViewControllerの「didFinishAnimating」デリゲートメソッドに依存している場合、それらは起動されないことに注意してください。代わりに、コードをdidFinishAnimatingから別のメソッドに移動し、setViewControllersメソッドの完了ブロックからそのメソッドを呼び出します。
DiscDev 2015

1
@thatzpremあなたがUIPageControlを継続して使用する場合は、あなたがしたいことがあります。presentationIndexForPageViewControllerリターンself.currentIndexため、その後self.currentIndex = viewControllerToMoveToのインデックス
ブレンダン・

@thatzpremは正しいです。同じページに移動するたび。たとえば、3つのページがある場合、毎回2ページ目のみに移動します。
Tushar Lathiya

18

私はここで完全に何かを見落としている可能性がありますが、この解決策は他の多くの提案よりもはるかに単純に思えます。

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
よく働く!どういうわけかページインジケーターも変更する必要があります。
TruMan1 2017

本当に役に立ちました!goToFirstPageの関数も教えてください。
マンタ2017年

同じページに移動するたび。たとえば、3つのページがある場合、毎回2ページ目のみに移動します。
Tushar Lathiya

15

このコードは私にとってうまくいきました、ありがとう。

これは私がそれでやったことです。前進または後退するためのいくつかの方法と、特定のページに直接移動するための方法。縦向きの6ページのドキュメント用です。pageViewControllerテンプレートのRootControllerの実装に貼り付ければ問題なく動作します。

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

    }

}

2ページあるランドスケープモードで使いたい。そこでの使い方。ご案内頂けますか?
iPhoneプログラムで

9

スウィフト4:

pagecontrollerビューコントローラーを次にタップして次のコントローラーに移動し、pageControlインデックスも更新する必要があるため、これが私にとって最良かつ最も簡単なソリューションでした

let pageController = self.parent as! PageViewController

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

pageController.pageControl.currentPage = 1

5

dataSourceのメソッドの使用についてはどうですか?

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

逆方向にも同様です。


3

ではスウィフト

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
この完全な例を教えてください。原因私はこのようなことをしています。この拡張機能をコードで使用する方法。よろしければ、コードをお送りします。
2015

2

ただし、この「self.pageViewController setViewControllers」メソッド呼び出しを使用しても、裏返されたページのviewControllerで「viewDidDissapear」は呼び出されません。一方、手動でページをめくると、裏切られたページでviewDidDissapearが呼び出されます。これが私のクラッシュの原因だと思います

「提供されたビューコントローラーの数(0)は、要求された遷移に必要な数(1)と一致しません」


使用してみてください。– pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:
Graham

2

また、PageViewControllerを左にナビゲートするためのボタンも必要でした。これは、スワイプモーションから期待するとおりの操作を行うためのものです。

自然なスワイプナビゲーションを処理するための「pageViewController:viewControllerBeforeViewController」の内部にすでにいくつかのルールが設定されていたため、ボタンですべてのコードを再利用し、特定のインデックスを使用する余裕がなかった以前のようにページに到達することを答えはしました。だから、私は別の解決策をとらなければなりませんでした。

次のコードは、カスタムViewController内のプロパティであり、スパインがmidに設定されているページビューコントローラー用であることに注意してください。

これが、左にナビゲートボタン用に記述したコードです。

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

ここから正しいナビゲーションボタンを作成するために、非常によく似た操作を実行できます。


2

場合は、現在のページを示すために、PAGE CONTROLがOである&&あなたがスクロールを介した&またページのViewControllerにカスタムボタンをクリックしてナビゲートするページをしたい場合は、以下の役に立つかもしれません。

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

//ユーザーが次のページにスクロールしたときにデリゲートがviewControllerAfterViewControllerを呼び出しました

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

}

//カスタムボタンの(前と次)ロジック

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

4つの質問に対してほぼ同じ答えを投稿しました。それらの1つが他の複製であると思われる場合は、そのようにマークする必要があります(同じ回答を何度も投稿しないでください)。
Jaap

だから私は他の同様の質問の上にこの質問のリンクを投稿できますが、解決策は同じです。
Yogesh Lolusare

1
何かを判断するつもりはありませんが、あなたのコードのフォーマットは私にとって非常に不快に見えます。
Lukas Petr 2017年

1
右@Lukas、今すぐフォーマットします。ありがとう
Yogesh Lolusare 2017年

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

}

//今、このメソッドを呼び出します

[self moveToPage];

私はそれがうまくいくことを願っています:)


1

1ページについては、@ 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

@samwizeが指摘したように、ページ分割の方法は

setViewControllers:array

ここに私がそれをした方法があります:私は私のデータソースとデリゲートを別々に持っています。このメソッドを呼び出して、「次の」ビューのみを変更できます。以前は、ページングルールを適用する必要があります。つまり、方向と次のコントローラを確認する必要があります。カスタムデータソースでそのメソッドを使用する場合、表示しているコントローラーの配列は変更されません(NSObjectサブクラスでカスタム配列を使用するため)。

独自のデータソースを使用して、メソッドは(特定の方向で)新しいビューを設定するだけです。通常のスワイプ時に表示されるページを引き続き制御します。


0

私は昨日からItに取り組んでおり、ようやくそれを実行しました。子ビューとして3つの異なるviewControllersがあるため、標準テンプレートを完全に使用できませんでした。

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

最初の1つのVCでのみトリガーボタンが必要だったので、pageViewControllerとモデルに1つのプロパティを追加しました。

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

@interface VC1 : UIViewController

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

@end

モデルのinitメソッドを書き直して、ストーリーボードとpageViewControllerをパラメーターとして渡すので、これらを自分の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;
}

最後に、vc1にIBActionを追加して、pageViewControllerメソッドsetViewControllers:direction:animated:completion:をトリガーします

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

VCインデックスを見つける必要がないことに注意してください。私のボタンは2番目のVCに移動しますが、すべてのインデックスを取得し、子ビューを追跡するのは難しくありません。

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

お役に立てば幸いです。


0

以下は、UIPageViewControllerDataSourceメソッドを使用したソリューションです

コードは、UIPageViewControllerで現在表示されているビューコントローラーを追跡します。

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

最初にcurrentViewControllerを初期化して、UIPageViewControllerに設定された初期ビューコントローラに設定します。

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

その後の追跡続けるcurrentViewControllerをしてUIPageViewControllerDelegateする:メソッドpageViewController:willTransitionToViewControllers: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;
    }
}

最後に、選択したメソッド(以下の例では-(IBAction)onNext:(id)sender)で、UIPageViewControllerDataSouceメソッドpageViewController:viewControllerBeforeViewController:pageViewController:viewControllerAfterViewController:を使用して、プログラムで次または前のコントローラーに切り替えることができます。次または前のビューコントローラー。[self.pageViewController setViewControllers:@ [vc] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion: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];
    }
}

詳細な説明は非常に役に立ちました。
Taslim Oseni

@TaslimOseniは、例が十分に明確ではなかったことを指摘してくれてありがとう。動作の説明を追加しました。さらに説明が必要な場合はお知らせください。
pconor

0

ViewControllersはPageViewControllerに埋め込まれているため、次の操作を行うだけです。

  • 親ビューコントローラーを取得し、関連するクラスとしてキャストします。
  • その親のdatasourceプロパティを使用して、次のViewControllerを取得します。
  • SetParentViewControllersメソッドを使用して、次のページに設定して移行します。

Xamarinの例ですが、機能的にはSwiftなどに似ています。次のコードは、ページとして表示されているいずれかのViewControllerのButton Clickデリゲートにあります。

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

parent.SetViewControllers(new UIViewController[] { next }, UIPageViewControllerNavigationDirection.Forward, true, null);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.