Skip to content

Instantly share code, notes, and snippets.

@astrokin
Created November 15, 2017 22:12
Show Gist options
  • Save astrokin/a110385a90d3e09eb8e681c2d1130d53 to your computer and use it in GitHub Desktop.
Save astrokin/a110385a90d3e09eb8e681c2d1130d53 to your computer and use it in GitHub Desktop.
PageViewController
protocol PageControllerIndexable: class {
var pageIndex: Int { get set }
}
protocol PageViewControllerDatasource: class {
var startingViewController: PageControllerIndexable? { get }
var nextViewController: PageControllerIndexable? { get }
var previousViewController: PageControllerIndexable? { get }
var currentIndex: Int { get }
}
protocol PageViewControllerDelegate: class {
func didChangeContentController(_ controller: PageControllerIndexable?)
}
class PageViewController: UIPageViewController {
weak var pagesDatasource: PageViewControllerDatasource?
weak var pagesDelegate: PageViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.clear
dataSource = self
delegate = self
assert(pagesDatasource != nil, "setup pagesDatasource")
if let vc = pagesDatasource!.startingViewController {
setViewControllers([vc as! UIViewController],
direction: .forward,
animated: false,
completion: nil)
vc.pageIndex = pagesDatasource!.currentIndex
pagesDelegate!.didChangeContentController(vc)
}
}
func forward() {
setup(contentController: pagesDatasource?.nextViewController, forDirection: .forward)
}
func backward() {
setup(contentController: pagesDatasource?.previousViewController, forDirection: .reverse)
}
}
// MARK: UIPageViewControllerDataSource
extension PageViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController) -> UIViewController? {
let previousVC = pagesDatasource!.previousViewController
previousVC?.pageIndex = (pagesDatasource!.currentIndex - 1)
return previousVC as? UIViewController
}
func pageViewController(_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController) -> UIViewController? {
let nextVC = pagesDatasource!.nextViewController
nextVC?.pageIndex = (pagesDatasource!.currentIndex + 1)
return nextVC as? UIViewController
}
}
// MARK: - UIPageViewControllerDelegate
extension PageViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController,
didFinishAnimating _: Bool,
previousViewControllers _: [UIViewController],
transitionCompleted completed: Bool) {
if !completed {
return
}
pagesDelegate!.didChangeContentController(pageViewController.viewControllers?.first as? PageControllerIndexable)
}
}
private extension PageViewController {
func setup(contentController viewController: PageControllerIndexable?, forDirection direction: UIPageViewControllerNavigationDirection) {
if let vc = viewController {
setViewControllers([vc as! UIViewController], direction: direction, animated: true, completion: nil)
let side = direction == .reverse ? (-1) : 1
vc.pageIndex = pagesDatasource!.currentIndex + side
pagesDelegate!.didChangeContentController(vc)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment