Last active
July 17, 2017 13:32
-
-
Save thefotes/65e97d1cf6dbe6e0c344e3ebe57839a1 to your computer and use it in GitHub Desktop.
This file contains 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 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