Created
November 4, 2020 14:27
-
-
Save JasonCanCode/03d7121c02d452340333fcdc6fcd9159 to your computer and use it in GitHub Desktop.
Convenient class embedding multiple view controllers inside a UIPageViewController
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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