CHIPageControlJaloro.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //
  2. // CHIPageControlJaloro.swift
  3. // CHIPageControl ( https://github.com/ChiliLabs/CHIPageControl )
  4. //
  5. // Copyright (c) 2017 Chili ( http://chi.lv )
  6. //
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining a copy
  9. // of this software and associated documentation files (the "Software"), to deal
  10. // in the Software without restriction, including without limitation the rights
  11. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. // copies of the Software, and to permit persons to whom the Software is
  13. // furnished to do so, subject to the following conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be included in
  16. // all copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. // THE SOFTWARE.
  25. import UIKit
  26. open class CHIPageControlJaloro: CHIBasePageControl {
  27. @IBInspectable open var elementWidth: CGFloat = 20 {
  28. didSet {
  29. setNeedsLayout()
  30. }
  31. }
  32. @IBInspectable open var elementHeight: CGFloat = 6 {
  33. didSet {
  34. setNeedsLayout()
  35. }
  36. }
  37. fileprivate var inactive = [CHILayer]()
  38. fileprivate var active = CHILayer()
  39. required public init?(coder aDecoder: NSCoder) {
  40. super.init(coder: aDecoder)
  41. }
  42. public override init(frame: CGRect) {
  43. super.init(frame: frame)
  44. }
  45. override func updateNumberOfPages(_ count: Int) {
  46. inactive.forEach { $0.removeFromSuperlayer() }
  47. inactive = [CHILayer]()
  48. inactive = (0..<count).map {_ in
  49. let layer = CHILayer()
  50. self.layer.addSublayer(layer)
  51. return layer
  52. }
  53. self.layer.addSublayer(active)
  54. setNeedsLayout()
  55. self.invalidateIntrinsicContentSize()
  56. }
  57. override open func layoutSubviews() {
  58. super.layoutSubviews()
  59. let floatCount = CGFloat(inactive.count)
  60. let x = (self.bounds.size.width - self.elementWidth*floatCount - self.padding*(floatCount-1))*0.5
  61. let y = (self.bounds.size.height - self.elementHeight)*0.5
  62. var frame = CGRect(x: x, y: y, width: self.elementWidth, height: self.elementHeight)
  63. active.cornerRadius = self.radius
  64. active.backgroundColor = (self.currentPageTintColor ?? self.tintColor)?.cgColor
  65. active.frame = frame
  66. inactive.enumerated().forEach() { index, layer in
  67. layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
  68. if self.borderWidth > 0 {
  69. layer.borderWidth = self.borderWidth
  70. layer.borderColor = self.tintColor(position: index).cgColor
  71. }
  72. layer.cornerRadius = self.radius
  73. layer.frame = frame
  74. frame.origin.x += self.elementWidth + self.padding
  75. }
  76. update(for: progress)
  77. }
  78. override func update(for progress: Double) {
  79. guard let min = inactive.first?.frame,
  80. let max = inactive.last?.frame,
  81. progress >= 0 && progress <= Double(numberOfPages - 1),
  82. numberOfPages > 1 else {
  83. return
  84. }
  85. let total = Double(numberOfPages - 1)
  86. let dist = max.origin.x - min.origin.x
  87. let percent = CGFloat(progress / total)
  88. let offset = dist * percent
  89. active.frame.origin.x = min.origin.x + offset
  90. }
  91. override open var intrinsicContentSize: CGSize {
  92. return sizeThatFits(CGSize.zero)
  93. }
  94. override open func sizeThatFits(_ size: CGSize) -> CGSize {
  95. return CGSize(width: CGFloat(inactive.count) * self.elementWidth + CGFloat(inactive.count - 1) * self.padding,
  96. height: self.elementHeight)
  97. }
  98. override open func didTouch(gesture: UITapGestureRecognizer) {
  99. let point = gesture.location(ofTouch: 0, in: self)
  100. if let touchIndex = inactive.enumerated().first(where: { $0.element.hitTest(point) != nil })?.offset {
  101. delegate?.didTouch(pager: self, index: touchIndex)
  102. }
  103. }
  104. }