【问题标题】:Is it possible to Turn page programmatically in UIPageViewController?是否可以在 UIPageViewController 中以编程方式翻页?
【发布时间】:2011-11-04 18:00:50
【问题描述】:

是否可以在UIPageViewController中以编程方式翻页?

【问题讨论】:

标签: ios ios5 uikit uipageviewcontroller


【解决方案1】:

是的,可以使用以下方法:

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

【讨论】:

  • 既然 NDA 已经启动,可以进一步扩展吗?也许是代码示例。
  • 我想我终于明白了这一点:UIPageViewController 并不真正关心它当前在哪个页面上。当您调用 setViewControllers 时,它可以使您看起来像是在动画地导航离开当前的视图控制器,但它并不是真的在寻找页面。
  • 示例:[self setViewControllers:@[vcToMoveTo] 方向:UIPageViewControllerNavigationDirectionForward 动画:YES 完成:nil]; // 其中 vcToMoveTo 是一个 UIViewController
  • 如果你想继续使用UIPageControl,那么你可能想要:self.currentIndex = viewControllerToMoveTo's index then for presentationIndexForPageViewController return self.currentIndex
  • 如果您还需要更新页面指示器显示,请检查stackoverflow.com/questions/22554877/…
【解决方案2】:

由于我也需要这个,我将详细介绍如何执行此操作。

注意:我假设您使用标准模板表单来生成 UIPageViewController 结构 - 在您调用它时会同时创建 modelViewControllerdataViewController。如果您不理解我写的内容,请返回并创建一个以UIPageViewController 为基础的新项目。到时候你就明白了。

因此,需要翻转到特定页面涉及设置上面列出的各种方法。对于这个练习,我假设它是一个显示两个视图的横向视图。另外,我将它实现为一个 IBAction,以便它可以通过按下按钮或其他方式来完成 - 它就像很容易使其选择器调用并传入所需的项目。

因此,对于此示例,您需要两个将显示的视图控制器 - 并且可选地,无论您是在书中前进还是后退。

请注意,我只是硬编码了转到第 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!  

}

【讨论】:

  • 我有同样的要求来移动到一个特定的页面。但是上面的代码似乎对我不起作用。我究竟做错了什么?我有 19 页。
  • 我们可以在通过数据源对象提供视图控制器时也使用这段代码 sn-p 吗?
  • Apple 的课程实施得非常糟糕。
【解决方案3】:

这是单页视图的另一个代码示例。 viewControllerAtIndex 的实现在这里省略了,它应该返回给定索引的正确视图控制器。

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

【讨论】:

  • 但是页面索引控件没有得到更新。我该怎么做?
  • 这个答案对我有用 - 但是请注意,如果您依赖 UIPageViewController 的“didFinishAnimating”委托方法,它们将不会被解雇。相反,将您的代码从 didFinishAnimating 移动到一个单独的方法,并从 setViewControllers 方法的完成块中调用该方法。
  • @thatzprem 如果你想继续使用 UIPageControl,那么你可能想要: self.currentIndex = viewControllerToMoveTo's index then for presentationIndexForPageViewController return self.currentIndex
  • @thatzprem 是对的。每次都转到同一页。例如,如果我们有 3 页,那么每次它只会转到第 2 页。
【解决方案4】:

我可能在这里完全遗漏了一些东西,但这个解决方案似乎比许多其他人提出的要简单得多。

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)
            }
        }
    }
}

【讨论】:

  • 效果很好!只需要以某种方式更改页面指示器。
  • 真的很有帮助!请给我们一个 goToFirstPage 的函数。
  • 每次都去同一个页面。例如如果我们有3页,那么每次它只会去第2页。
  • 很好的解决方案。
【解决方案5】:

这段代码很适合我,谢谢。

这就是我所做的。一些用于前进或后退的方法,以及一种用于直接进入特定页面的方法。它适用于纵向视图的 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];

    }

}

【讨论】:

  • 我想将它用于存在两个页面的横向模式。如何在那里使用它。你能指导一下吗?
【解决方案6】:

斯威夫特 4:

当我在 pagecontroller 视图控制器上点击 next 并更新 pageControl 索引时,我需要转到下一个控制器,所以这是最好和最直接的解决方案对我来说

let pageController = self.parent as! PageViewController

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

pageController.pageControl.currentPage = 1

【讨论】:

    【解决方案7】:

    使用 dataSource 中的方法怎么样?

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

    向后类推。

    【讨论】:

      【解决方案8】:

      但是,使用此“self.pageViewController setViewControllers”方法调用不会在已关闭页面的 viewController 上调用“viewDidDissapear”,而手动翻页会在已关闭页面上调用 viewDidDissapear。我相信这是我崩溃的原因

      “提供的视图控制器数量 (0) 与请求的转换所需的数量 (1) 不匹配”

      【讨论】:

      • 尝试使用:– pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:
      【解决方案9】:

      Swift 中:

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

      【讨论】:

      • 你能给我一个完整的例子吗?因为我正在做这样的事情。如何在我的代码中使用这个扩展。如果您愿意,我可以将代码发送给您。
      【解决方案10】:

      我还需要一个按钮来在 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];
          }
      }
      

      你可以做一些非常相似的事情来从这里制作一个右导航按钮。

      【讨论】:

        【解决方案11】:

        如果 如果 PAGE CONTROL 指示当前页面是 O && 您希望页面通过滚动导航以及单击 Page 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;
        }
        

        }

        //自定义按钮的(Prev & next)逻辑

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

        【讨论】:

        • 您对四个问题发布了几乎完全相同的答案。如果您认为其中一个与另一个重复,您应该将它们标记为这样(并且不要多次发布相同的答案)。
        • 所以我可以将这个问题的链接发布到其他类似问题上,但解决方案是相同的。
        • 我不是要评判什么的,但是你的代码格式让我很反感。
        • 对@Lukas,我现在将对其进行格式化。谢谢
        【解决方案12】:
        - (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];

        我希望它有效:)

        【讨论】:

          【解决方案13】:

          对于单页,我刚刚编辑了@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];
          }
          

          【讨论】:

            【解决方案14】:

            正如@samwize 指出的那样,分页的方式是使用

            setViewControllers:array
            

            这是我的做法: 我有我的数据源和委托分开。您可以调用此方法并且只更改“下一个”视图。以前您必须应用分页规则。 也就是说,您必须检查方向和下一个控制器。如果您将该方法与您的自定义数据源一起使用,您正在显示的控制器数组将不会改变(因为您将在 NSObject 子类上使用自定义数组)。

            使用您自己的数据源,该方法只是设置一个新视图(具有特定方向)。因为您仍然可以控制正常滑动时显示的页面。

            【讨论】:

              【解决方案15】:

              我从昨天开始就在努力,我终于做到了。我不能完全使用标准模板,因为我有三个不同的视图控制器作为子视图:

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

              我只在第一个 VC 中需要一个触发按钮,所以我为 pageViewController 和模型添加了一个属性:

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

              注意我不需要查找 VCs 索引,我的按钮会将我带到我的第二个 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];
              }
              

              希望对你有帮助!

              【讨论】:

                【解决方案16】:

                这是一个使用 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];
                }
                
                
                

                然后在 UIPageViewControllerDelegate 方法中跟踪 currentViewControllerpageViewController: 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] 方向:UIPageViewControllerNavigationDirectionForward 动画:YES 完成: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];
                    }
                }
                
                

                【讨论】:

                • 详细的解释会非常有用。
                • @TaslimOseni 感谢您指出示例不够清晰。我添加了它如何工作的描述,如果需要更多解释,请告诉我。
                【解决方案17】:

                由于 ViewController 嵌入在 PageViewController 中,您所要做的就是:

                • 检索父视图控制器并转换为您的相关类。
                • 使用父数据源属性获取下一个 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);
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2013-02-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-08-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多