Skip to content

Instantly share code, notes, and snippets.

@thefotes
Last active July 17, 2017 13:32
Show Gist options
  • Save thefotes/65e97d1cf6dbe6e0c344e3ebe57839a1 to your computer and use it in GitHub Desktop.
Save thefotes/65e97d1cf6dbe6e0c344e3ebe57839a1 to your computer and use it in GitHub Desktop.
import Foundation
protocol PJPageControlUsable {
var indicatorType: PJPageControl.Indicator { get }
}
protocol PJPageControlDelegate: class {
func alertIndicatorPressed(pageControl: PJPageControl)
}
final class PJPageControl: NSObject {
enum Indicator {
case dot
case alert
func indicator() -> UIView {
switch self {
case .dot:
let image = UIImage(named: "paging-dot-active")!
let imageView = UIImageView(image: image)
return imageView
case .alert:
let button = UIButton(type: .custom)
let image = UIImage(named: "alert-bell")!
button.setImage(image, for: .normal)
return button
}
}
}
var indicators: [Indicator] {
didSet {
self.configure(with: indicators)
}
}
var totalNumberOfPages: Int {
return self.indicators.count
}
var currentPage: Int {
didSet {
self.makePageActive(page: currentPage)
}
}
var pageIndicatorColor = UIColor(red: 81 / 255, green: 81 / 255, blue: 81 / 255, alpha: 1.0)
var currentPageIndicatorColor = UIColor(red: 219 / 255, green: 219 / 255, blue: 219 / 255, alpha: 1.0)
weak var delegate: PJPageControlDelegate?
let stackView: UIStackView
override init() {
let sv = UIStackView()
sv.spacing = 9
sv.distribution = .fill
sv.alignment = .center
sv.translatesAutoresizingMaskIntoConstraints = false
self.currentPage = 0
self.stackView = sv
self.indicators = []
super.init()
}
private func makePageActive(page: Int) {
guard !self.stackView.arrangedSubviews.isEmpty else { return }
self.stackView.arrangedSubviews.forEach({ view in
if let view = view as? ColorTemplateable {
view.renderImage(with: self.pageIndicatorColor)
}
view.transform = .identity
})
let view = self.stackView.arrangedSubviews[page]
if case PJPageControl.Indicator.dot = self.indicators[page] {
view.transform = CGAffineTransform(scaleX: 1.13, y: 1.13)
}
if let view = view as? ColorTemplateable {
view.renderImage(with: self.currentPageIndicatorColor)
}
}
private func resetStackView() {
for subview in self.stackView.arrangedSubviews {
self.stackView.removeArrangedSubview(subview)
subview.removeFromSuperview()
}
}
private func configure(with indicators: [Indicator]) {
resetStackView()
let imageViews = indicators.map({ return $0.indicator() })
imageViews.forEach({ view in
if let view = view as? ColorTemplateable {
view.renderImage(with: self.pageIndicatorColor)
}
if let view = view as? UIButton {
view.addTarget(self, action: #selector(PJPageControl.alertButtonPressed(sender:)), for: .touchUpInside)
}
self.stackView.addArrangedSubview(view)
})
}
@objc private func alertButtonPressed(sender: UIButton) {
self.delegate?.alertIndicatorPressed(pageControl: self)
}
}
protocol ColorTemplateable {
func renderImage(with color: UIColor)
}
extension UIImageView: ColorTemplateable {
func renderImage(with color: UIColor) {
let image = self.image?.withRenderingMode(.alwaysTemplate)
self.tintColor = color
self.image = image
}
}
extension UIButton: ColorTemplateable {
func renderImage(with color: UIColor) {
let image = self.image(for: .normal)?.withRenderingMode(.alwaysTemplate)
self.tintColor = color
self.setImage(image, for: .normal)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment