167

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

4

17 に答える 17

248

はい、次の方法で可能です:

- (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)
于 2011-08-30T08:45:32.093 に答える
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!  

}
于 2011-11-04T21:43:31.543 に答える
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];

    }

}
于 2011-12-30T10:11:39.020 に答える
5

dataSource のメソッドを使用するのはどうですか?

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

類推的に後方に。

于 2015-10-09T16:18:19.580 に答える
3

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

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

于 2012-09-21T11:52:43.133 に答える
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
        }
    }

}
于 2015-06-06T17:53:45.837 に答える
2

また、PageViewControllerを左に移動するためのボタンも必要でした。これは、スワイプモーションから期待されることを正確に実行する必要があります。

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

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

[左に移動]ボタン用に作成したコードは次のとおりです。

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

ここから右のナビゲーションボタンを作成するのと非常によく似たことができます。

于 2013-02-10T21:06:53.080 に答える
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];

}

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

[自己 moveToPage];

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

于 2017-09-19T09:23:18.773 に答える
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];
}
于 2015-06-27T09:15:31.620 に答える
0

私は昨日からそれに取り組んでいて、ついに仕事をしました。子ビューとして3つの異なるビューコントローラーがあるため、標準テンプレートを完全に使用できませんでした:

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 メソッドを書き直して、storyboard と 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];
}

お役に立てば幸いです。

于 2014-06-10T00:41:00.563 に答える