如何在视图控制器之间同步索引

How to sync index between view controllers

我想实现类似 PageMenu 的东西。目前,我有一个根视图控制器,里面有 2 个容器,名为 headerViewControllercontainerViewController 我已经设置好一切,但我不知道如何同步这两个视图控制器之间的行为。

- 如何将我的索引从 UICollectionViewController 发送到 UIPageViewController?

- UIPageViewController 做 Scroll 时,如何更改 UICollectionViewController 中的索引?

rootViewController

var headerViewController: PageMenuViewController?
var containerViewController: PageViewController?

override func awakeFromNib() {
    pages = [Pages(name: "Page1", selected: true, url: photo1), Pages(name: "Page2", url: video1)]
}

override func viewDidLoad() {
    super.viewDidLoad()
}

// MARK: Navigation
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "rootViewSegue" {
        containerViewController = segue.destination as? PageViewController
        containerViewController!.controllerArray = pages
    } else if segue.identifier == "headerViewSegue" {
        headerViewController = segue.destination as? PageMenuViewController
        headerViewController!.dataArray = pages
    }
}

containerViewController(UIPageViewController)

func jumpToPage(_ index: Int) {
    if index < orderedViewControllers.count {
        setViewControllers([orderedViewControllers[index]], direction: .forward, animated: true, completion: nil)
    }
}

headerViewController (UICollectionViewController)

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    // Sync index with containerViewController
    // How to use jumpToPage ??
}

您可以使用委托模式,rootViewController 将实现协议 containerViewControllerDelegateheaderViewControllerDelegate,因此您可以通过这些委托传递数据。

如果您需要示例,请告诉我。

根据@SaintThread 的回答。 protocol/delegate 适合我。

RootViewController

class ViewController: UIViewController, PageMenuDelegate, PageViewDelegate {

// MARK: Data Source
let photo1 = Bundle.main.url(forResource: "pageView", withExtension: ".png")!
let video1 = Bundle.main.url(forResource: "ElephantSeals", withExtension: ".mov")!
var pages = [Pages]()

var headerViewController: PageMenuViewController?
var containerViewController: PageViewController?

var currentIndex = 0

override func awakeFromNib() {
    pages = [Pages(name: "Page1", selected: true, url: photo1), Pages(name: "Page2", url: video1)]
}

override func viewDidLoad() {
    super.viewDidLoad()
    headerViewController?.delegate = self
    containerViewController?.containerDelegate = self
}

// MARK: Navigation
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "rootViewSegue" {
        containerViewController = segue.destination as? PageViewController
        containerViewController!.controllerArray = pages
    } else if segue.identifier == "headerViewSegue" {
        headerViewController = segue.destination as? PageMenuViewController
        headerViewController!.dataArray = pages
    }
}

// Delegate in CollectionViewController
func selectItem(at index: Int) {
    containerViewController?.pageIndex = index
    currentIndex = index
}

// Delegate in UIPageViewController
func scrollTo(_ index: Int) {
    headerViewController?.setSelectedItem(at: IndexPath(row: index, section: 0))
    currentIndex = index
}

}

CollectionViewController

protocol PageMenuDelegate {
    func selectItem(at index: Int)
}

class PageMenuViewController: UIViewController {
    var delegate: PageMenuDelegate?
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        setSelectedItem(at: indexPath)
        delegate?.selectItem(at: indexPath.row) // HERE
    }

    func setSelectedItem(at indexPath: IndexPath) {
        for i in 0..<dataArray.count {
            dataArray[i].selected = false
        }
        dataArray[indexPath.row].selected = true
        collectionView.reloadData()
    }
}

PageViewController

protocol PageViewDelegate {
    func scrollTo(_ index: Int)
}

class PageViewController: UIPageViewController {
    var containerDelegate: PageViewDelegate? // "delegate" collides with pageview delegate

    var pageIndex: Int = 0 {
        didSet {
            jumpToPage(pageIndex)
            containerDelegate?.scrollTo(pageIndex) //HERE
        }
    }

    func jumpToPage(_ index: Int) {
        if index < orderedViewControllers.count {
            setViewControllers([orderedViewControllers[index]], direction: .forward, animated: true, completion: nil)
        }
    }
}

extension PageViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        ... pageIndex = index //HERE
    }
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        ... pageIndex = index //HERE

    }
}