Skip to content

Instantly share code, notes, and snippets.

@nathanborror
Created September 27, 2016 21:28
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 nathanborror/dc62ef3c267760c1fafc5584ab89318d to your computer and use it in GitHub Desktop.
Save nathanborror/dc62ef3c267760c1fafc5584ab89318d to your computer and use it in GitHub Desktop.
//
// PagerController.swift
//
import UIKit
open class PagerController: BaseViewController {
let scrollView = UIScrollView()
let viewControllers: [UIViewController]
let startingPage: Int
public var onShake: (() -> Void)?
public init(viewControllers: [UIViewController], startAt page: Int = 1) {
self.viewControllers = viewControllers
self.startingPage = page
super.init(nibName: nil, bundle: nil)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
open override func viewDidLoad() {
super.viewDidLoad()
automaticallyAdjustsScrollViewInsets = false
scrollView.delegate = self
scrollView.frame = view.bounds
scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
scrollView.isPagingEnabled = true
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
scrollView.isDirectionalLockEnabled = true
view.addSubview(scrollView)
for (i, vc) in viewControllers.enumerated() {
self.addChildViewController(vc)
scrollView.addSubview(vc.view)
vc.didMove(toParentViewController: self)
var frame = vc.view.frame
frame.origin.x = CGFloat(i) * frame.width
vc.view.frame = frame
vc.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
vc.automaticallyAdjustsScrollViewInsets = false
scrollView.contentSize = CGSize(width: vc.view.frame.maxX, height: scrollView.frame.height)
}
scrollTo(page: startingPage, animated: false)
}
open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let position = CGPoint(x: 0, y: topLayoutGuide.length)
let size = CGSize(width: view.bounds.width, height: view.bounds.height - position.y)
scrollView.frame = CGRect(origin: position, size: size)
scrollView.contentSize = CGSize(width: scrollView.contentSize.width, height: size.height)
}
public func scrollTo(page: Int, animated: Bool) {
let index = page - 1
guard index < viewControllers.count else { return }
let vc = viewControllers[index]
scrollView.scrollRectToVisible(vc.view.frame, animated: animated)
}
open override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) {
guard motion == .motionShake else { return }
onShake?()
}
}
extension PagerController: UIScrollViewDelegate {
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
let offset = scrollView.contentOffset
for vc in viewControllers {
if vc.view.frame.minX == offset.x {
vc.viewDidDisappear(true)
}
}
}
public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
let offset = scrollView.contentOffset
for vc in viewControllers {
if vc.view.frame.minX == offset.x {
vc.viewDidAppear(true)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment