PageViewController - 自动滑动 - Swift 3

PageViewController - Auto Slide - Swift 3

我正在尝试同时自动滑动页面视图控制器页面和页面指示器。我的页面视图控制器中有 5 个页面。从图 1-5 开始,流程运行良好,但我无法从第 5 个图像返回到第一个图像并重新启动自动滑动。

下面是我的代码:

import UIKit

class PageSliderViewController: UIViewController , UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    @IBOutlet weak var pageControl: UIPageControl!

    var pageContainer: UIPageViewController!

    // The pages it contains
    var pages = [UIViewController]()

    // Track the current index
    var currentIndex: Int?
    private var pendingIndex: Int?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Setup the pages
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let page1: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page1")
        let page2: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page2")
        let page3: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page3")
        let page4: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page4")
        let page5: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page5")
        pages.append(page1)
        pages.append(page2)
        pages.append(page3)
        pages.append(page4)
        pages.append(page5)
        // Create the page container
        pageContainer = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
        pageContainer.delegate = self
        pageContainer.dataSource = self
        pageContainer.setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)

        currentIndex = 0

        // Add it to the view
        view.addSubview(pageContainer.view)

        // Configure our custom pageControl
        self.view.bringSubview(toFront: self.loginButton)
        self.view.bringSubview(toFront: self.signUpButton)
        self.view.bringSubview(toFront: self.pageControl)
        pageControl.numberOfPages = pages.count
        pageControl.currentPage = 0

        Timer.scheduledTimer(timeInterval: 5,
                             target: self,
                             selector: #selector(self.next(_:)),
                             userInfo: nil,
                             repeats: true)

    }

    func next(_ timer: Timer) {
        pageContainer.goToNextPage()
        currentIndex = currentIndex! + 1
        if currentIndex == pageControl.numberOfPages{
            currentIndex = 0
        }
        pageControl.currentPage = currentIndex!
    }

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

    // MARK: - UIPageViewController delegates

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        let currentIndex = pages.index(of: viewController)!
        if currentIndex == 0 {
            return nil
        }
        let previousIndex = abs((currentIndex - 1) % pages.count)
        return pages[previousIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let currentIndex = pages.index(of: viewController)!
        if currentIndex == pages.count-1 {
            return nil
        }
        let nextIndex = abs((currentIndex + 1) % pages.count)
        return pages[nextIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
        pendingIndex = pages.index(of: pendingViewControllers.first!)
    }

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if completed {
            currentIndex = pendingIndex
            if let index = currentIndex {
                pageControl.currentPage = index
            }
        }
    }
}

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

请注意,通过此代码,页面控件从第 5 个点变为第 1 个点,但页面没有变化。有一些小错误,但无法弄清楚。任何帮助将不胜感激!

我没有试过运行这段代码,但我的猜测是:

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
    let currentIndex = pages.index(of: viewController)!
    if currentIndex == pages.count-1 {
        return nil
    }
    let nextIndex = abs((currentIndex + 1) % pages.count)
    return pages[nextIndex]
}

数组是从零开始的,所以如果您当前正在查看 page5,那么您正在查看 pages[4] ... 而 pages.count - 1 等于 4。因此,您的代码是说:

if the current page is page5
    return nil

因此您的 func goToNextPage() 分机调用 viewControllerAfter 并在 return 中获得 nil

您很可能想将 viewControllerAfter 更改为:

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
    let currentIndex = pages.index(of: viewController)!

    // you don't need this, because you are using % modulo operator
    // to keep "nextIndex" within the array bounds
    //if currentIndex == pages.count-1 {
    //    return nil
    //}

    let nextIndex = abs((currentIndex + 1) % pages.count)
    return pages[nextIndex]
}