Skip to content

Instantly share code, notes, and snippets.

@Que20
Created December 7, 2020 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Que20/bb4a0c15278830d8c2397ab4f47c8be6 to your computer and use it in GitHub Desktop.
Save Que20/bb4a0c15278830d8c2397ab4f47c8be6 to your computer and use it in GitHub Desktop.
A simple paged view controller implementation.
import Foundation
import UIKit
protocol PagerViewControllerDelegate: class {
func pagerViewController(controller: PagerViewController,
didUpdatePageCount count: Int)
func pagerViewController(controller: PagerViewController,
didUpdatePageIndex index: Int)
}
class PagerViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pagerDelegate: PagerViewControllerDelegate?
var pages: [UIViewController] = []
var pageControl: UIPageControl = {
let pageControl = UIPageControl()
pageControl.translatesAutoresizingMaskIntoConstraints = false
return pageControl
}()
convenience init(viewControllers: [UIViewController]) {
self.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
self.pages = viewControllers
self.pageControl.numberOfPages = viewControllers.count
}
override init(transitionStyle style: UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [UIPageViewController.OptionsKey : Any]? = nil) {
super.init(transitionStyle: style, navigationOrientation: navigationOrientation, options: options)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
self.view.addSubview(self.pageControl)
NSLayoutConstraint.activate([
self.pageControl.leftAnchor.constraint(equalTo: self.view.leftAnchor),
self.pageControl.rightAnchor.constraint(equalTo: self.view.rightAnchor),
self.pageControl.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor)
])
if let initialViewController = self.pages.first {
self.scrollToViewController(viewController: initialViewController)
self.pageControl.currentPage = 0
}
self.pagerDelegate?.pagerViewController(controller: self, didUpdatePageCount: self.pages.count)
}
func scrollToViewController(index newIndex: Int) {
if let firstViewController = viewControllers?.first,
let currentIndex = self.pages.firstIndex(of: firstViewController) {
let direction: UIPageViewController.NavigationDirection = newIndex >= currentIndex ? .forward : .reverse
let nextViewController = self.pages[newIndex]
self.scrollToViewController(viewController: nextViewController, direction: direction)
}
}
func scrollToViewController(viewController: UIViewController, direction: UIPageViewController.NavigationDirection = .forward) {
self.setViewControllers([viewController], direction: direction, animated: true, completion: { (finished) -> Void in
self.pageIndexDidChanged()
})
}
func pageIndexDidChanged() {
if let firstViewController = viewControllers?.first, let index = self.pages.firstIndex(of: firstViewController) {
self.pageControl.currentPage = index
self.pagerDelegate?.pagerViewController(controller: self, didUpdatePageIndex: index)
}
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = self.pages.firstIndex(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return self.pages.last
}
guard self.pages.count > previousIndex else {
return nil
}
return self.pages[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = self.pages.firstIndex(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
guard self.pages.count != nextIndex else {
return self.pages.first
}
guard self.pages.count > nextIndex else {
return nil
}
return self.pages[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
self.pageIndexDidChanged()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment