You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

130 lines
3.4 KiB

//
import Foundation
import UIKit
@IBDesignable
class CustomPageControl: UIControl {
//MARK:- Properties
private var numberOfDots = [UIView]() {
didSet{
if numberOfDots.count == numberOfPages {
setupViews()
}
}
}
@IBInspectable var numberOfPages: Int = 0 {
didSet{
for tag in 0 ..< numberOfPages {
let dot = getDotView()
dot.tag = tag
dot.backgroundColor = pageIndicatorTintColor
self.numberOfDots.append(dot)
}
}
}
var currentPage: Int = 0 {
didSet{
onPageControlSwipe()
}
}
@IBInspectable var pageIndicatorTintColor: UIColor? = .blue
@IBInspectable var currentPageIndicatorTintColor: UIColor? = .green
private lazy var stackView = UIStackView.init(frame: self.bounds)
private lazy var constantSpace = ((stackView.spacing) * CGFloat(numberOfPages - 1) + ((self.bounds.height * 0.45) * CGFloat(numberOfPages)) - self.bounds.width)
override var bounds: CGRect {
didSet{
self.numberOfDots.forEach { (dot) in
self.setupDotAppearance(dot: dot)
}
}
}
//MARK:- Intialisers
convenience init() {
self.init(frame: .zero)
}
init(withNoOfPages pages: Int) {
self.numberOfPages = pages
self.currentPage = 0
super.init(frame: .zero)
setupViews()
}
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setupViews() {
self.numberOfDots.forEach { (dot) in
self.stackView.addArrangedSubview(dot)
}
stackView.alignment = .center
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(stackView)
self.addConstraints([
stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
stackView.heightAnchor.constraint(equalTo: self.heightAnchor),
])
self.numberOfDots.forEach { dot in
self.addConstraints([
dot.centerYAnchor.constraint(equalTo: self.stackView.centerYAnchor),
dot.widthAnchor.constraint(equalToConstant: 7),
dot.heightAnchor.constraint(equalToConstant: 7),
])
}
self.numberOfDots.forEach { dot in
dot.layer.cornerRadius = dot.bounds.height / 2
}
}
@objc private func onPageControlSwipe() {
_ = numberOfDots.map { (dot) in
setupDotAppearance(dot: dot)
if dot.tag == currentPage {
UIView.animate(withDuration: 0.2, animations: {
dot.layer.cornerRadius = dot.bounds.height / 5
dot.transform = CGAffineTransform.init(scaleX: 2, y: 1)
dot.backgroundColor = self.currentPageIndicatorTintColor
})
}
}
}
//MARK: Helper methods...
private func getDotView() -> UIView {
let dot = UIView()
dot.translatesAutoresizingMaskIntoConstraints = false
self.setupDotAppearance(dot: dot)
return dot
}
private func setupDotAppearance(dot: UIView) {
dot.transform = .identity
dot.layer.cornerRadius = dot.bounds.height / 2
dot.layer.masksToBounds = true
dot.backgroundColor = pageIndicatorTintColor
}
}