Swift UIPageView - 如何获取PageControll的索引?

时间:2018-01-15 23:41:45

标签: ios swift uipageviewcontroller uipagecontrol

我试图让pageControl指示符点工作,但我无法找到如何让当前的viewController将pageControl.currentPage设置为正确的索引。

这是我设置UIPageController

的方法
class PageViewController: UIPageViewController, UIPageViewControllerDataSource {

var pageControl = UIPageControl()

lazy var viewControllerList: [UIViewController] = {

    let sb = UIStoryboard(name: "Main", bundle: nil)

    let vc1 = sb.instantiateViewController(withIdentifier: "VC1")
    let vc2 = sb.instantiateViewController(withIdentifier: "VC2")
    let vc3 = sb.instantiateViewController(withIdentifier: "VC3")

    return [vc1, vc2, vc3]
}()

override func viewDidLoad() {
    super.viewDidLoad()

    //  seting up the dots
    pageControl.frame = CGRect(x: view.frame.midX - 50, y: view.frame.maxY - 80, width: 100, height: 100)
    pageControl.numberOfPages = 3
    pageControl.currentPage = 0
    view.addSubview(pageControl)
    view.bringSubview(toFront: pageControl)


    self.dataSource = self

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

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

    let prevIndex = viewControllerIndex - 1
    guard prevIndex >= 0 else {return nil}
    guard viewControllerList.count > prevIndex else {return nil}

    return viewControllerList[prevIndex]

}

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

    let nextIndex = viewControllerIndex + 1
    guard viewControllerList.count != nextIndex else {return nil}
    guard viewControllerList.count > nextIndex else {return nil}

    return viewControllerList[nextIndex]
}
}

我在这里尝试了几个答案,但似乎没有一个在我的案例中起作用。如何找出将pageControl.currentPage设置为正确索引的当前索引(我想我必须在函数viewControllerBeforeviewControllerAfter中设置它?

我尝试使用viewControllerIndex(previewIndex或nextIndex)但这会让点指针从第一个点跳到第三个点(不是随机的,但也没有订购)。

2 个答案:

答案 0 :(得分:2)

如果实现了所需的UIPageViewControllerDataSource方法,UIPageViewController会显示一个内置页面指示符。来自文档:

  

如果实现了支持页面指示器中的两个方法并且页面视图控制器的过渡样式是滚动,则页面指示器可见。

所需的方法是:

public func presentationCount(for pageViewController: UIPageViewController) -> Int
public func presentationIndex(for pageViewController: UIPageViewController) -> Int

但是您的示例使用自定义UIPageControl而不是内置页面指示符。该方法提供了更大的灵活性例如,虽然内置控件始终位于视图的底部,但您可以轻松地将自定义控件放在视图的顶部。

要将自定义UIPageControl连接到UIPageViewController,您必须实现UIPageViewControllerDelegate。这允许设置pageControl.currentPage以响应滑动手势。为此:

在您的班级中添加会员:

var pendingPage: Int?

设置代理:

override func viewDidLoad() {
    ...
    self.delegate = self
    ...
}

并实现委托协议的一些方法。我更喜欢为每个协议添加一个扩展,以便明确地对协议名称及其实现进行分组。

extension PageViewController: UIPageViewControllerDelegate { 
    // Sent when a gesture-initiated transition begins.
    func pageViewController(_ pageViewController: UIPageViewController,
                            willTransitionTo pendingViewControllers: [UIViewController]) {
        pendingPage = viewControllerList.index(of: pendingViewControllers.first!)
    }

    // Sent when a gesture-initiated transition ends. The 'finished' parameter indicates whether the animation finished,
    // while the 'completed' parameter indicates whether the transition completed or bailed out (if the user let go early).
    func pageViewController(_ pageViewController: UIPageViewController,
                            didFinishAnimating finished: Bool,
                            previousViewControllers: [UIViewController],
                            transitionCompleted completed: Bool) {
        guard completed, let page = pendingPage else {
            return
        }
        pageControl.currentPage = page
    }
}

答案 1 :(得分:0)

我使用了msmolens的答案,但没有使用扩展程序:

    class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    var pageControl = UIPageControl()

    lazy var viewControllerList: [UIViewController] = {

        let sb = UIStoryboard(name: "Main", bundle: nil)

        let vc1 = sb.instantiateViewController(withIdentifier: "VC1")
        let vc2 = sb.instantiateViewController(withIdentifier: "VC2")
        let vc3 = sb.instantiateViewController(withIdentifier: "VC3")

        return [vc1, vc2, vc3]
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = self

        //  seting up the dots

        pageControl.frame = CGRect(x: view.frame.midX - 50, y: view.frame.maxY - 80, width: 100, height: 100)
        pageControl.numberOfPages = 3
        pageControl.currentPage = 0
        view.addSubview(pageControl)
        view.bringSubview(toFront: pageControl)


        self.dataSource = self

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

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

        let prevIndex = viewControllerIndex - 1
        guard prevIndex >= 0 else {return nil}
        guard viewControllerList.count > prevIndex else {return nil}

        return viewControllerList[prevIndex]

    }

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

        let nextIndex = viewControllerIndex + 1
        guard viewControllerList.count != nextIndex else {return nil}
        guard viewControllerList.count > nextIndex else {return nil}

        return viewControllerList[nextIndex]
    }

     // Sent when a gesture-initiated transition begins.

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

    // Sent when a gesture-initiated transition ends. The 'finished' parameter indicates whether the animation finished,
    // while the 'completed' parameter indicates whether the transition completed or bailed out (if the user let go early).

    func pageViewController(_ pageViewController: UIPageViewController,
                            didFinishAnimating finished: Bool,
                            previousViewControllers: [UIViewController],
                            transitionCompleted completed: Bool) {
        guard completed, let page = pendingPage else {
            return
        }
        pageControl.currentPage = page
        }
    }