Swift中的PageViewController当前页面索引

时间:2015-09-28 12:17:27

标签: ios swift uiviewcontroller uipageviewcontroller uipagecontrol

我想获取pageViewController的当前索引,我不知道如何获取可见页面索引。

func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool)
{
    // How to get it?

}

12 个答案:

答案 0 :(得分:31)

您可以使用didFinishAnimating,并将标签设置为viewcontrollers。试试这个

func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
   if (!completed)
  {
    return
  }
  self.pageControl.currentPageIndex = pageViewController.viewControllers!.first!.view.tag //Page Index
}

答案 1 :(得分:13)

将此代码添加到您的UIPageViewController

var pages = [UIViewController]()
var currentIndex: Int {
    guard let vc = viewControllers?.first else { return 0 }
    return pages.firstIndex(of: vc) ?? 0
}

答案 2 :(得分:9)

Swift 3:完整的程序化PageViewController示例,用于在没有视图标记的情况下获取/设置当前页面索引:

enum PageViewType:String {
        case green = "greenView"
        case blue = "blueView"
        case red = "redView"  
}

class MyPageViewController: UIPageViewController {

    private (set) lazy var orderedViewControllers:[UIViewController] = {
         return [self.newPageView(.green),
                self.newPageView(.blue),
                self.newPageView(.red)
        ]
    }

    var currentIndex:Int {
            get {
                return orderedViewControllers.index(of: self.viewControllers!.first!)!
            }

            set {
                guard newValue >= 0,
                    newValue < orderedViewControllers.count else {
                    return
                }

                let vc = orderedViewControllers[newValue]
                let direction:UIPageViewControllerNavigationDirection = newValue > currentIndex ? .forward : .reverse            
                self.setViewControllers([vc], direction: direction, animated: true, completion: nil) 
            }
        }

    override func viewDidLoad() {
        super.viewDidLoad()

        dataSource = self

        if let firstViewController = orderedViewControllers.first {
            setViewControllers([firstViewController],
                           direction: .forward,
                           animated: true,
                           completion: nil)
        }
    }

    private func newPageView(_ viewType:PageViewType) -> UIViewController {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: viewType.rawValue)       
        return vc
    }
}

UIPageViewController DataSource实现:

extension MyPageViewController:UIPageViewControllerDataSource {

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        let previousIndex = currentIndex - 1

        guard previousIndex >= 0 else {
            return nil
        }

        guard orderedViewControllers.count > previousIndex else {
            return nil
        }

        return orderedViewControllers[previousIndex]   
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {         
        let nextIndex = currentIndex + 1

        guard orderedViewControllers.count != nextIndex else {
            return nil
        }

        guard orderedViewControllers.count > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }

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

    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {

        return currentIndex
    }
}

答案 3 :(得分:9)

在Swift 3中

像这样覆盖UIPageViewControllerDelegate的didFinishAnimating函数:

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if completed {
        if let currentViewController = pageViewController.viewControllers![0] as? WalkthroughContentViewController {
            pageControl.currentPage = currentViewController.index
        }
    }
}

其中WalkthroughContentViewController是UIPageViewController提供的UIViewController

请记住在WalkthroughContentViewController中保留一个索引变量。另外,在viewDidLoad方法中设置:

delegate = self

答案 4 :(得分:2)

您可以使用下一个方法:

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    guard
        completed,
        let viewControllerIndex = tutorialViews.index(of: pageViewController.viewControllers!.first!) else
            return
        }

    self.currentIndex = viewControllerIndex
}

tutorialViews 是一个页面数组(ViewControllers)。
并初始化 currentIndex ,如下所示:

var currentIndex = 0 {
    didSet {
        self.updateContentForPage(withIndex: currentIndex)
    }
}

答案 5 :(得分:1)

试试..

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

self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
    }

答案 6 :(得分:1)

首先,让您的UIPageViewController实现UIPageViewControllerDataSource方法$('body').on('click', '.addpa1', function(e){ e.preventDefault(); console.log('.addpa1 clicked'); $('#display_details').load('project_member_list.php', function() { console.log( 'Load was performed.' ); }); }); 以返回每个PageViewController的ViewController的索引。

然后在您的委托中,通过传入的PageViewController访问数据源:

presentationIndex(for pageViewController: UIPageViewController) -> Int

答案 7 :(得分:0)

别忘了设置pageviewcontroller的委托。

 func createPageViewController() {
    // Create page view controller
    pageViewController = storyboard?.instantiateViewController(withIdentifier: "PageViewController") as? UIPageViewController
    pageViewController?.delegate = self
    pageViewController?.dataSource = self

    let startingViewController: ChildViewController = viewControllerAtIndex(index: 0)!
    let viewControllers: Array = [startingViewController]
    pageViewController?.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)

    self.addChildViewController(pageViewController!)
    self.view.frame = CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height)
    self.view.addSubview((pageViewController?.view)!)
    self.pageViewController?.didMove(toParentViewController: self)
}

func viewControllerAtIndex(index: Int) -> ChildViewController? {  
    // return nil here, if there won't be any page in pageviewcontroller

    // Create a new view controller and pass suitable data.
    let pageContentViewController: ChildViewController = storyboard?.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController

    pageContentViewController.pageIndex = index
    return pageContentViewController
}

//Also add viewControllerAfter and viewControllerBefore methods

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    self.pendingIndex = (pendingViewControllers.first as! ChildViewController).pageIndex
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if completed {
        self.currentIndex = self.pendingIndex!
        //Perform your task here
    }
}

答案 8 :(得分:0)

例如在类-> WalkthroughPageViewController中创建一个方法,例如:

class WalkthroughContentViewController: UIViewController {

@IBOutlet var headingLabel: UILabel!
@IBOutlet var contentLabel: UILabel!
@IBOutlet var forwardButton: UIButton!
@IBOutlet var pageControl: UIPageControl!
@IBOutlet var contentImageView: UIImageView!

var index     = 0
var heading   = ""
var content   = ""
var imageFile = ""

override func viewDidLoad() {
    super.viewDidLoad()

    headingLabel.text = heading
    contentLabel.text = content
    contentImageView.image = UIImage(named: imageFile)

    // Update the 'currentPage' property of the page control.
    pageControl.currentPage = index

    if case 0...1 = index {
        forwardButton.setTitle("NEXT", for : .normal)
    } else if case 2 = index {
        forwardButton.setTitle("DONE", for : .normal)
    }
}

// MARK: - Actions

@IBAction func nextButtonTapped(sender: UIButton) {
    switch index {
    case 0...1: /* Get the parent controller & call to the "forward" method from the 'WalkthroughPageViewController'. */
        let pageViewController = parent as! WalkthroughPageViewController
        pageViewController.forward(index: index)
    case 2: /* Dismiss the page view controller and show the main screen of the app*/
        dismiss(animated: true, completion: nil)
    default: break
    }
}

在控制所述UIPageController的类中,该类将是一个控制器视图(类-> WalkthroughContentViewController),并且包含一个传递到下一页并更新属性“ pageControl.currentPage”(其本身就是UIpageControl),实现:

cat example1.txt
example:42:udajha:llama:04
example:22:udajha:llama:02

}

答案 9 :(得分:0)

只需检查apple的文档(https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit)->第3节->步骤5

您可以像这样获取当前索引

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
            if completed,
                let visibleViewController = pageViewController.viewControllers?.first,
                let index = parent.controllers.firstIndex(of: visibleViewController)
            {
                parent.currentPage = index
            }
        }

或者如果您将viewControllers保留在数组中,您可以这样做

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if completed,
            let visibleViewController = pageViewController.viewControllers?.first,
            let index = orderedViewControllers.firstIndex(of: visibleViewController)
        {
            statisticsPageDelegate?.statisticsPageViewController(statisticsPageViewController: self, didUpdatePageIndex: index)
        }
    }

这是完整的代码

class StatisticsPageViewController: UIPageViewController,UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    var currentIndex: Int?
    var statisticsPageDelegate: StatisticsPageViewControllerDelegate?
    private var pendingIndex: Int?

    required init?(coder aDecoder: NSCoder) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        dataSource = self
        delegate = self

        if let firstViewController = orderedViewControllers.first {
            setViewControllers([firstViewController],
                               direction: .forward,
                               animated: true,
                               completion: nil)
        }

        statisticsPageDelegate?.statisticsPageViewController(
            statisticsPageViewController: self,
            didUpdatePageCount: orderedViewControllers.count
        )
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.index(of:viewController) else {
            return nil
        }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else {
            return nil
        }

        guard orderedViewControllers.count > previousIndex else {
            return nil
        }

        return orderedViewControllers[previousIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.index(of:viewController) else {
            return nil
        }

        let nextIndex = viewControllerIndex + 1
        let orderedViewControllersCount = orderedViewControllers.count

        guard orderedViewControllersCount != nextIndex else {
            return nil
        }

        guard orderedViewControllersCount > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if completed,
            let visibleViewController = pageViewController.viewControllers?.first,
            let index = orderedViewControllers.firstIndex(of: visibleViewController)
        {
            statisticsPageDelegate?.statisticsPageViewController(statisticsPageViewController: self, didUpdatePageIndex: index)
        }
    }

    private(set) lazy var orderedViewControllers: [UIViewController] = {
        return [self.newStatisticsViewController(identifier: Identifiers.PROGRAM_VIEW_CONTROLLER),
        self.newStatisticsViewController(identifier: Identifiers.LOGIN_VIEW_CONTROLLER)]
    }()

    private func newStatisticsViewController(identifier: String) -> UIViewController {
        return UIStoryboard(name: "Main", bundle: nil) .
            instantiateViewController(withIdentifier: identifier)
    }
}

protocol StatisticsPageViewControllerDelegate: class {
    func statisticsPageViewController(statisticsPageViewController:
        StatisticsPageViewController, didUpdatePageCount count: Int)
    func statisticsPageViewController(statisticsPageViewController:
        StatisticsPageViewController, didUpdatePageIndex index: Int)
}

答案 10 :(得分:0)

使用viewDidAppear将页面标记为可见,将viewDidDisappear标记页面视为不可见

Item ViewController:

class PageItemViewController: UIViewController {

    private(set) var isVisible: Bool = false

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        isVisible = true
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        isVisible = false
    }   
}

获取可见页面的索引

class PageViewController: UIPageViewController, UIPageViewControllerDelegate {

    var items: [PageItemViewController] = [] {
        didSet {
            if let last = items.last {
                setViewControllers([last], direction: .forward, animated: true, completion: nil)
            }
        }
    }

    // ...

    public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if finished {
            guard let currentIndex = items.firstIndex(where: { $0.isVisible }) else { return }
            print(currentIndex)
        }
    }
}

答案 11 :(得分:0)

Swift 4版本

使用这些协议(UIPageViewControllerDelegateUIPageViewControllerDataSource)扩展ViewController类并添加以下功能有助于我使页面控件正常工作。

class ViewController : UIPageViewControllerDelegate,UIPageViewControllerDataSource {

    func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
        if let viewController = pendingViewControllers[0] as? DataViewController {
            self.lastPendingViewControllerIndex = viewController.index!
        }
    }

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if completed {
            pageControl.currentPage = self.lastPendingViewControllerIndex
            if lastPendingViewControllerIndex == 4 {
                self.getstartedButton.isHidden=false
            } else {
                self.getstartedButton.isHidden=true
            }
        }
    }
}