Skip to content

Commit

Permalink
Added support to Multiple Tint Colors (#35)
Browse files Browse the repository at this point in the history
* Added an array of tintColors for the layer's backgrounds on the BasePageControl
* Added support of the TintColors on the different PageControls
* Updated README to show the usage of multiple tint colors
* Added an example of how to add the colored page control
  • Loading branch information
nunoonun authored and chili-ios committed Dec 29, 2017
1 parent fcb3cff commit 6c19bf5
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 38 deletions.
6 changes: 3 additions & 3 deletions CHIPageControl/CHIPageControlAji.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ open class CHIPageControlAji: CHIBasePageControl {
active.backgroundColor = (self.currentPageTintColor ?? self.tintColor)?.cgColor
active.frame = frame

inactive.forEach() { layer in
layer.backgroundColor = self.tintColor.withAlphaComponent(self.inactiveTransparency).cgColor
inactive.enumerated().forEach() { index, layer in
layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
if self.borderWidth > 0 {
layer.borderWidth = self.borderWidth
layer.borderColor = self.tintColor.cgColor
layer.borderColor = self.tintColor(position: index).cgColor
}
layer.cornerRadius = self.radius
layer.frame = frame
Expand Down
6 changes: 3 additions & 3 deletions CHIPageControl/CHIPageControlAleppo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ open class CHIPageControlAleppo: CHIBasePageControl {
active.backgroundColor = (self.currentPageTintColor ?? self.tintColor)?.cgColor
active.frame = frame

inactive.forEach() { layer in
layer.backgroundColor = self.tintColor.withAlphaComponent(self.inactiveTransparency).cgColor
inactive.enumerated().forEach() { index, layer in
layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
if self.borderWidth > 0 {
layer.borderWidth = self.borderWidth
layer.borderColor = self.tintColor.cgColor
layer.borderColor = self.tintColor(position: index).cgColor
}
layer.cornerRadius = self.radius
layer.frame = frame
Expand Down
4 changes: 2 additions & 2 deletions CHIPageControl/CHIPageControlChimayo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ open class CHIPageControlChimayo: CHIBasePageControl {
let y = (self.bounds.size.height - self.diameter)*0.5
var frame = CGRect(x: x, y: y, width: self.diameter, height: self.diameter)

inactive.forEach() { layer in
inactive.enumerated().forEach() { index, layer in
layer.cornerRadius = self.radius
layer.frame = frame
frame.origin.x += self.diameter + self.padding
layer.backgroundColor = self.tintColor.cgColor
layer.backgroundColor = self.tintColor(position: index).cgColor
}
update(for: progress)
}
Expand Down
11 changes: 7 additions & 4 deletions CHIPageControl/CHIPageControlFresno.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ open class CHIPageControlFresno: CHIBasePageControl {
let y = (self.bounds.size.height - self.diameter)*0.5
var frame = CGRect(x: x, y: y, width: self.diameter, height: self.diameter)

elements.forEach() { layer in
layer.backgroundColor = self.tintColor.withAlphaComponent(self.inactiveTransparency).cgColor
elements.enumerated().forEach() { index, layer in
layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
if self.borderWidth > 0 {
layer.borderWidth = self.borderWidth
layer.borderColor = self.tintColor.cgColor
layer.borderColor = self.tintColor(position: index).cgColor
}
layer.cornerRadius = self.radius
layer.frame = frame
Expand Down Expand Up @@ -127,12 +127,14 @@ open class CHIPageControlFresno: CHIBasePageControl {
guard frames.indices.contains(index - 1), frames.indices.contains(index) else { return }

let prev = frames[index - 1]
let prevColor = tintColor(position: index - 1)
let current = frames[index]
let currentColor = tintColor(position: index)

let elementTotal: CGFloat = current.origin.x - prev.origin.x
let elementProgress: CGFloat = current.origin.x - active.frame.origin.x
let elementPercent = (elementTotal - elementProgress) / elementTotal

// x: input, a: input min, b: input max, c: output min, d: output max
// returns mapped value x from (a,b) to (c, d)
let linearTransform = { (x: CGFloat, a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat) -> CGFloat in
Expand All @@ -141,6 +143,7 @@ open class CHIPageControlFresno: CHIBasePageControl {

element.frame = prev
element.frame.origin.x = linearTransform(elementPercent, 1.0, 0.0, prev.origin.x, current.origin.x)
element.backgroundColor = blend(color1: currentColor, color2: prevColor, progress: elementPercent).withAlphaComponent(self.inactiveTransparency).cgColor

if elementPercent <= 0.5 {
let originY = linearTransform(elementPercent, 0.0, 0.5, 0, self.radius + self.padding)
Expand Down
6 changes: 3 additions & 3 deletions CHIPageControl/CHIPageControlJalapeno.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ open class CHIPageControlJalapeno: CHIBasePageControl {
let y = (self.bounds.size.height - self.diameter)*0.5
var frame = CGRect(x: x, y: y, width: self.diameter, height: self.diameter)

inactive.forEach() { layer in
layer.backgroundColor = self.tintColor.withAlphaComponent(self.inactiveTransparency).cgColor
inactive.enumerated().forEach() { index, layer in
layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
if self.borderWidth > 0 {
layer.borderWidth = self.borderWidth
layer.borderColor = self.tintColor.cgColor
layer.borderColor = self.tintColor(position: index).cgColor
}
layer.cornerRadius = self.radius
layer.frame = frame
Expand Down
6 changes: 3 additions & 3 deletions CHIPageControl/CHIPageControlJaloro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ open class CHIPageControlJaloro: CHIBasePageControl {
active.backgroundColor = (self.currentPageTintColor ?? self.tintColor)?.cgColor
active.frame = frame

inactive.forEach() { layer in
layer.backgroundColor = self.tintColor.withAlphaComponent(self.inactiveTransparency).cgColor
inactive.enumerated().forEach() { index, layer in
layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
if self.borderWidth > 0 {
layer.borderWidth = self.borderWidth
layer.borderColor = self.tintColor.cgColor
layer.borderColor = self.tintColor(position: index).cgColor
}
layer.cornerRadius = self.radius
layer.frame = frame
Expand Down
16 changes: 12 additions & 4 deletions CHIPageControl/CHIPageControlPaprika.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ open class CHIPageControlPaprika: CHIBasePageControl {
let y = (self.bounds.size.height - self.diameter)*0.5
var frame = CGRect(x: x, y: y, width: self.diameter, height: self.diameter)

elements.forEach() { layer in
layer.backgroundColor = self.tintColor.withAlphaComponent(self.inactiveTransparency).cgColor
elements.enumerated().forEach() { index, layer in
layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
if self.borderWidth > 0 {
layer.borderWidth = self.borderWidth
layer.borderColor = self.tintColor.cgColor
layer.borderColor = self.tintColor(position: index).cgColor
}
layer.cornerRadius = self.radius
layer.frame = frame
Expand Down Expand Up @@ -139,9 +139,17 @@ open class CHIPageControlPaprika: CHIBasePageControl {
guard frames.indices.contains(page), frames.indices.contains(page + 1) else { return }

let prev = frames[page]
let prevColor = tintColor(position: page)
let current = frames[page + 1]
let currentColor = tintColor(position: page + 1)

let elementTotal: CGFloat = current.origin.x - prev.origin.x
let elementProgress: CGFloat = current.origin.x - active.frame.origin.x
let elementPercent = (elementTotal - elementProgress) / elementTotal

element.borderColor = blend(color1: currentColor, color2: prevColor, progress: elementPercent).cgColor
element.frame = prev
element.frame.origin.x += current.origin.x - active.frame.origin.x
element.frame.origin.x += elementProgress
element.frame.origin.y = 2*min.origin.y - active.frame.origin.y
}

Expand Down
16 changes: 12 additions & 4 deletions CHIPageControl/CHIPageControlPuya.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ open class CHIPageControlPuya: CHIBasePageControl {
let y = (self.bounds.size.height - self.diameter)*0.5
var frame = CGRect(x: x, y: y, width: self.diameter, height: self.diameter)

elements.forEach() { layer in
layer.backgroundColor = self.tintColor.withAlphaComponent(self.inactiveTransparency).cgColor
elements.enumerated().forEach() { index, layer in
layer.backgroundColor = self.tintColor(position: index).withAlphaComponent(self.inactiveTransparency).cgColor
if self.borderWidth > 0 {
layer.borderWidth = self.borderWidth
layer.borderColor = self.tintColor.cgColor
layer.borderColor = self.tintColor(position: index).cgColor
}
layer.cornerRadius = self.radius
layer.frame = frame
Expand Down Expand Up @@ -121,9 +121,17 @@ open class CHIPageControlPuya: CHIBasePageControl {
guard frames.indices.contains(page), frames.indices.contains(page + 1) else { return }

let prev = frames[page]
let prevColor = tintColor(position: page)
let current = frames[page + 1]
let currentColor = tintColor(position: page + 1)

let elementTotal: CGFloat = current.origin.x - prev.origin.x
let elementProgress: CGFloat = current.origin.x - active.frame.origin.x
let elementPercent = (elementTotal - elementProgress) / elementTotal

element.backgroundColor = blend(color1: currentColor, color2: prevColor, progress: elementPercent).withAlphaComponent(self.inactiveTransparency).cgColor
element.frame = prev
element.frame.origin.x += current.origin.x - active.frame.origin.x
element.frame.origin.x += elementProgress
}

override open var intrinsicContentSize: CGSize {
Expand Down
53 changes: 53 additions & 0 deletions CHIPageControl/Core/CHIBasePageControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import UIKit

@IBInspectable open var numberOfPages: Int = 0 {
didSet {
populateTintColors()
updateNumberOfPages(numberOfPages)
self.isHidden = hidesForSinglePage && numberOfPages <= 1
}
Expand Down Expand Up @@ -83,6 +84,15 @@ import UIKit
setNeedsLayout()
}
}

open var tintColors: [UIColor] = [] {
didSet {
guard tintColors.count == numberOfPages else {
fatalError("The number of tint colors needs to be the same as the number of page")
}
setNeedsLayout()
}
}

@IBInspectable open var currentPageTintColor: UIColor? {
didSet {
Expand Down Expand Up @@ -122,6 +132,35 @@ import UIKit
}
}

func tintColor(position: Int) -> UIColor {
if tintColors.count < numberOfPages {
return tintColor
} else {
return tintColors[position]
}
}

open func insertTintColor(_ color: UIColor, position: Int) {
if tintColors.count < numberOfPages {
setupTintColors()
}
tintColors[position] = color
}

private func setupTintColors() {
tintColors = Array<UIColor>(repeating: tintColor, count: numberOfPages)
}

private func populateTintColors() {
guard tintColors.count > 0 else { return }

if tintColors.count > numberOfPages {
tintColors = Array(tintColors.prefix(numberOfPages))
} else if tintColors.count < numberOfPages {
tintColors.append(contentsOf: Array<UIColor>(repeating: tintColor, count: numberOfPages - tintColors.count))
}
}

func animate() {
guard let moveToProgress = self.moveToProgress else { return }

Expand Down Expand Up @@ -159,3 +198,17 @@ import UIKit
fatalError("Should be implemented in child class")
}
}

extension CHIBasePageControl {
internal func blend(color1: UIColor, color2: UIColor, progress: CGFloat) -> UIColor {
let l1 = 1 - progress
let l2 = progress
var (r1, g1, b1, a1): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0)
var (r2, g2, b2, a2): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0)

color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)

return UIColor(red: l1*r1 + l2*r2, green: l1*g1 + l2*g2, blue: l1*b1 + l2*b2, alpha: l1*a1 + l2*a2)
}
}
15 changes: 15 additions & 0 deletions Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
Expand Down Expand Up @@ -29,6 +39,11 @@
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
Expand Down
Loading

0 comments on commit 6c19bf5

Please sign in to comment.