【问题标题】:UIPageViewController: return the current visible viewUIPageViewController:返回当前可见视图
【发布时间】:2012-01-14 02:40:45
【问题描述】:

您如何知道UIPageViewController 中显示的当前页面/视图是什么?

我已经覆盖了我的子视图的 viewDidAppear 方法,以便它们在 viewDidAppear 方法中向父视图发送一个 id。

但是,问题在于:我不能可靠地使用该 id 作为显示页面的 id。因为如果用户翻页但中途决定停止翻页并放回页面,viewDidAppear 将已经被调用。 (视图在卷曲页面后面可见)。

也许我应该只在当前视图消失时才切换到新的 id。但我想知道是否没有更简单的方法来返回当前可见的视图?

【问题讨论】:

  • 你试过用viewDidAppear:animated:代替吗?
  • 哦,是的。我确实用过。我编辑了问题以纠正我的错误。
  • 您编辑问题的方式对我来说毫无意义。您可以从 viewWillAppear 或 viewDidAppear 中发送该 ID。请重新检查您的编辑。
  • 抱歉,我在编辑问题时做得不好。我一直使用 viewDidAppear。我希望我的最后一次编辑能澄清这一点。
  • 看看这里的家伙,这对我有用stackoverflow.com/a/36860663/4286947

标签: iphone ios uipageviewcontroller


【解决方案1】:

您应该手动跟踪当前页面。

委托方法pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: 将告诉您何时更新该变量。 transitionCompleted: 方法的最后一个参数可以告诉您用户是否完成了翻页转换。

然后,你可以通过做得到当前呈现的View Controller

self.viewControllers?.first

【讨论】:

  • +1 表示正确答案 - 我希望我有机会使用 UIPageViewController 并仅支持 iOS5。
  • 谢谢,这正是我正在寻找的干净解决方案。比页面上的代表更好。
  • 旋转设备时,如何跟踪当前页面?
  • @直到可以,只需将项目的最低版本设置为 ios5.0
  • 如何判断是增加还是减少当前页码?
【解决方案2】:

我通过使用一个小函数并将 pageIndex 指定为静态 NSInteger 来跟踪页面索引。

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

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

并在 Ole 指定的函数内调用[self setPageIndex];,并且在检测到方向变化之后也是如此。

【讨论】:

    【解决方案3】:

    以 Ole 的回答为基础……

    这就是我实现跟踪当前页面并将页面指示器更新为正确索引的 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;
    
    }
    

    【讨论】:

    • 我认为最后一行应该是self.nextIndex = self.currentIndex而不是self.nextIndex = 0,以便在转换未完成时正确恢复索引。否则,当您在页面中间某处快速来回翻页时,您可能会面临currentIndex 值为 0 的风险。
    • 这对我来说并不完全有效。有时,pageViewController:willTransitionToViewControllers 没有被调用,因此 nextIndex 没有改变,那么当前索引是错误的。
    【解决方案4】:

    我第一次使用 Corey 的解决方案,但它在 iOS5 上不起作用,然后最终使用,

    - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{
    
        if(completed) {
            _currentViewController = [pageViewController.viewControllers lastObject];
        }
    }
    

    它尝试在不同的页面之间切换,现在效果很好。

    【讨论】:

      【解决方案5】:

      从 iOS 6 开始,我发现 UIPageViewController 的 viewControllers 属性会不断更新,以便它始终拥有一个代表当前页面的视图控制器,而没有别的。因此,您可以通过调用viewControllers[0] 访问当前页面(假设您一次只显示一个视图控制器)。

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

      但是请注意cmets这是不可靠的。

      【讨论】:

      • 我发现它不可靠。我找不到问题的根源。当动画完成时,我访问 viewControllers 属性并获得正确的视图控制器,但是当我旋转时,在方法 spineLocationForInterfaceOrientation 上,我不再获得正确的视图控制器。所以我坚持维护自己的 currentPage 属性,而不是总是依赖viewControllers
      • 有趣,我会用它来看看它在这些特殊情况下的表现
      • 我也发现它不可靠。似乎 Apple 只是为每个翻页调用 viewControllerBeforeViewController 或 viewControllerAfterViewController,但没有更新 UIPageViewController.viewControllers。我不知道他们是如何一直把这些类型的事情弄错的,但他们确实做到了。它确实增加了我的工作量,并破坏了我的代码的清晰度(经常违反 D.R.Y. 和其他原则)。
      • @ZackMorris。这绝对令人难以置信,你说得对。这是一个“苹果的恐怖时刻”。为什么哦,为什么它们不包含明显的功能,例如向右移动一个,我当前在哪个页面上等等等等。令人难以置信的是,您无法“获取您所在的页面!!!”
      • self.viewControllers[0] 似乎对我来说很好用。但我只是在启动期间调用 setViewControllers 一次,其余的留给自动化。 (在 iOS 8.4 中测试)
      【解决方案6】:

      以下解决方案对我有用。

      Apple 可以通过使本机 UIPageViewController 滚动视图分页更具可配置性来避免很多麻烦。我不得不求助于覆盖新的 UIView 和 UIPageControl 只是因为本机 UIPageViewController 分页不支持透明背景或在视图框架内重新定位。

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

      【讨论】:

      • 在这你所说的索引是什么意思?
      • 我正在获取索引(即表示当前视图控制器在 self.pageViewController.viewControllers 数组中的位置的整数),然后使用它来设置 self 的 currentPage 属性。 pageControl(需要一个整数值)。有意义吗?
      • index 在这里我相信是一个自定义属性
      • 这个问题是如果你想改变页面没有动画方法不会被调用
      【解决方案7】:

      不幸的是,以上所有方法都没有帮助我。尽管如此,我还是通过使用标签找到了解决方案。可能它不是最好的,但它有效,希望它可以帮助某人:

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

      示例: gist

      【讨论】:

      • 这似乎是最直接的,对我来说效果很好。我在添加视图控制器时设置了标签(例如,HelpPage1ViewController *page1 = [self.storyboard instantiateViewControllerWithIdentifier:@"page1"];page1.view.tag=0;)。然后,您可以为主视图控制器设置 currentPage 属性以跟踪您的位置。请务必添加两个协议(“”),而不仅仅是数据源,并将委托设置为 self(“self.pageViewController.delegate=self;”),否则不会调用该方法。这让我有点困惑。
      • @VictorM 这个解决方案对我不起作用。我有一个带有不同图像的 pageViewController。每次滑动都会返回标签 0,知道为什么会这样吗?提前致谢
      • @VictorM 我花了几天时间试图保存索引,但意外找到了这个答案,我希望我能投票 1000 次,谢谢!
      • 很好的解决方案感谢您花了几个小时试图解决这个问题
      • 它只返回一个值 0。我做错了什么
      【解决方案8】:
      - (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
      

      【讨论】:

        【解决方案9】:

        我已经使用view.tag 有一段时间了,试图跟踪当前页面太复杂了。

        在此代码中,索引存储在每个viewtag 属性中,用于获取下一个或上一个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
          }
        }
        

        【讨论】:

          【解决方案10】:
          UIViewController *viewController = [pageViewController.viewControllers objectAtIndex:0];
          NSUInteger currentIndex = [(ViewController*) viewController indexNumber];
          

          它将返回当前页面索引。并且必须在 UIPageViewController (didFinishAnimating) 的委托函数下使用这段代码。

          【讨论】:

            【解决方案11】:

            不幸的是,以上对我没有任何作用。

            我有两个视图控制器,当我稍微(大约 20 像素)向后滚动最后一个视图时,它会触发委托:

            pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:

            并说当前页面(索引)是0 这是错误的。

            在子视图控制器中使用委托,例如:

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

            为我工作。

            【讨论】:

              【解决方案12】:

              这对我来说很可靠

              我有一个自定义 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
                    }
              

              【讨论】:

                【解决方案13】:

                下面的演示代码(在 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
                    }
                
                }
                

                【讨论】:

                  【解决方案14】:

                  斯威夫特 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?。第一个是有问题的?
                  • 其实很简单,viewControllers 数组只包含当前呈现的视图控制器。
                  • 如何从该函数中访问索引变量?
                  【解决方案15】:

                  感谢您的回答,我遇到了类似的问题,必须存储索引。我稍微修改了我的代码,粘贴在下面:

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

                  【讨论】:

                    【解决方案16】:

                    我有一个 viewControllers 数组,显示在 UIPageViewController 中。

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

                    这里要注意的重要一点是 UIPageViewControllersetViewControllers 方法不提供任何委托回调。委托回调仅代表 UIPageViewController 中的用户触摸操作。

                    【讨论】:

                      【解决方案17】:

                      这是我想出的解决方案:

                      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
                      

                      确保设置初始标题

                      【讨论】:

                        【解决方案18】:

                        处理此恕我直言,最简单的方法是使用 PageControl 来存储转换的潜在结果,然后在转换被取消时恢复。这意味着一旦用户开始滑动页面控件就会改变,这对我来说是可以的。这要求您拥有自己的 UIViewController 数组(在此示例中称为 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
                            }
                        }
                        

                        【讨论】:

                          【解决方案19】:

                          直接从UIPageViewController(Swift 4 版本)请求viewController 怎么样:

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

                          或者,如果您在某个时间点只需要当前呈现的视图控制器,则只需在那个时候使用pageViewController.viewControllers?.first

                          【讨论】:

                            【解决方案20】:

                            在 swift 5 和以下 sirvine 回答

                            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

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2013-09-14
                              • 1970-01-01
                              • 1970-01-01
                              • 2015-10-19
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2016-07-25
                              相关资源
                              最近更新 更多