I want to get current index of a pageViewController, I don\'t know how I get the visible pages index.
func pageViewController(pageViewController: UIPageViewContr         
        Try it..
func pageViewController(pageViewController: UIPageViewController,didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool){
guard completed else { return }
self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
    }
Dont forget to set pageviewcontroller's delegate.
 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
    }
}
Create a method within, for example, class -> WalkthroughPageViewController), such that:
 /* The method takes in a page index and creates the next content view controller. If the controller can
 be created, we call the built-in setViewControllers method and navigate to the next view controller.*/
func forward(index: Int) {
    if let nextViewController = contentViewController(at: index + 1) {
        setViewControllers([nextViewController], direction: .forward, animated: true, completion: nil)
    }
}
And in the class that controls said UIPageController, which will be a controller view (class -> WalkthroughContentViewController) and that contains a following button that passes to the next page and updates the property "pageControl.currentPage" (which is itself the UIpageControl), implements:
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
    }
}
}
You can use didFinishAnimating, and set tags to viewcontrollers. try this
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
}
Use viewDidAppear that mark page as visible and viewDidDisappear that mark page as invisible
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
    }   
}
Get index of the visible page
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)
        }
    }
}
In Swift 3
Override didFinishAnimating function of UIPageViewControllerDelegate like this:
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
        }
    }
}
where WalkthroughContentViewController is the UIViewController presented by UIPageViewController
Remember to keep an index variable inside the WalkthroughContentViewController. Also, in the viewDidLoad method set:
delegate = self