Skip to content

Instantly share code, notes, and snippets.

@JasonCanCode
Created November 4, 2020 14:27
Show Gist options
  • Save JasonCanCode/03d7121c02d452340333fcdc6fcd9159 to your computer and use it in GitHub Desktop.
Save JasonCanCode/03d7121c02d452340333fcdc6fcd9159 to your computer and use it in GitHub Desktop.
Convenient class embedding multiple view controllers inside a UIPageViewController
import UIKit
public protocol PageContainerDelegate: class {
func switchedPage(to index: Int, isLastPage: Bool)
}
open class PagedContentViewController: UIPageViewController {
public weak var containerDelegeate: PageContainerDelegate?
open var orderedViewControllers: [UIViewController] = [] {
didSet {
if let firstViewController = orderedViewControllers.first {
setViewControllers(
[firstViewController],
direction: .forward,
animated: false,
completion: nil
)
}
}
}
open override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
self.delegate = self
}
}
// MARK: - Data source functions
extension PagedContentViewController: UIPageViewControllerDataSource {
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.firstIndex(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
// User is on the first view controller and swiped left to loop to
// the last view controller.
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.firstIndex(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
// User is on the last view controller and swiped right to loop to
// the first view controller.
guard orderedViewControllersCount != nextIndex else {
return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
}
// MARK: - Delegate functions
extension PagedContentViewController: UIPageViewControllerDelegate {
public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard let pageContentViewController = pageViewController.viewControllers?.first,
let pageIndex = orderedViewControllers.firstIndex(of: pageContentViewController) else {
return
}
containerDelegeate?.switchedPage(to: pageIndex, isLastPage: pageIndex == orderedViewControllers.count - 1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment