Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AT] add horizontal gradient capability #44

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions TTSegmentedControl.playground/Contents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import PlaygroundSupport
let mainView = UIView(frame: CGRect(x: 0, y: 0, width: 350, height: 667))
mainView.backgroundColor = UIColor.white


var segmentedC5: TTSegmentedControl = TTSegmentedControl()
var segmentedC4: TTSegmentedControl = TTSegmentedControl()
var segmentedC3: TTSegmentedControl = TTSegmentedControl()
var segmentedC2: TTSegmentedControl = TTSegmentedControl()
Expand All @@ -17,8 +17,7 @@ segmentedC1.frame = CGRect(x: 14, y: 73, width: 322, height: 76)
segmentedC2.frame = CGRect(x: 14, y: 186, width: 322, height: 47)
segmentedC3.frame = CGRect(x: 14, y: 299, width: 322, height: 47)
segmentedC4.frame = CGRect(x: 14, y: 417, width: 133, height: 35)


segmentedC5.frame = CGRect(x: 14, y: 500, width: 322, height: 47)

//SegmentedControl 1

Expand All @@ -27,7 +26,8 @@ segmentedC1.allowChangeThumbWidth = false
segmentedC1.selectedTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.3))
segmentedC1.defaultTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.01))
segmentedC1.cornerRadius = 5
segmentedC1.useGradient = false
segmentedC1.useVerticalGradient = false
segmentedC1.useHorizontalGradient = true
segmentedC1.useShadow = false
segmentedC1.thumbColor = TTSegmentedControl.UIColorFromRGB(0xD9D72B)

Expand All @@ -40,7 +40,8 @@ segmentedC2.selectedTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weig
segmentedC2.defaultTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.01))
segmentedC2.cornerRadius = 0
segmentedC2.useShadow = false
segmentedC2.useGradient = true
segmentedC2.useVerticalGradient = true
segmentedC1.useHorizontalGradient = false
segmentedC2.thumbGradientColors = [ TTSegmentedControl.UIColorFromRGB(0xFE2C5A), TTSegmentedControl.UIColorFromRGB(0xF10EAE)]


Expand All @@ -50,7 +51,8 @@ segmentedC3.itemTitles = ["XS","S","M","L","XL"]
segmentedC3.allowChangeThumbWidth = false
segmentedC3.selectedTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.3))
segmentedC3.defaultTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.01))
segmentedC3.useGradient = true
segmentedC3.useVerticalGradient = true
segmentedC3.useHorizontalGradient = false
segmentedC3.useShadow = true
segmentedC3.thumbShadowColor = TTSegmentedControl.UIColorFromRGB(0x22C6E7)
segmentedC3.thumbGradientColors = [ TTSegmentedControl.UIColorFromRGB(0x25D0EC), TTSegmentedControl.UIColorFromRGB(0x1EA3D8)]
Expand All @@ -64,17 +66,34 @@ segmentedC3.didSelectItemWith = { index, title in
segmentedC4.itemTitles = ["OFF","ON"]
segmentedC4.selectedTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.3))
segmentedC4.defaultTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.01))
segmentedC4.useGradient = false
segmentedC4.useVerticalGradient = false
segmentedC4.useHorizontalGradient = false
segmentedC4.thumbColor = TTSegmentedControl.UIColorFromRGB(0x1FDB58)
segmentedC4.useShadow = true
segmentedC4.thumbShadowColor = TTSegmentedControl.UIColorFromRGB(0x56D37C)
segmentedC4.allowChangeThumbWidth = false


//SegmentedControl 5

segmentedC5.itemTitles = ["XS","S","M","L","XL"]
segmentedC5.allowChangeThumbWidth = false
segmentedC5.selectedTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.3))
segmentedC5.defaultTextFont = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight(0.01))
segmentedC5.useVerticalGradient = false
segmentedC5.useHorizontalGradient = true
segmentedC5.useShadow = true
segmentedC5.thumbShadowColor = TTSegmentedControl.UIColorFromRGB(0x22C6E7)
segmentedC5.thumbGradientColors = [ TTSegmentedControl.UIColorFromRGB(0x25D0EC), TTSegmentedControl.UIColorFromRGB(0x1EA3D8)]
segmentedC5.didSelectItemWith = { index, title in
print(index)
}

mainView.addSubview(segmentedC1)
mainView.addSubview(segmentedC2)
mainView.addSubview(segmentedC3)
mainView.addSubview(segmentedC4)

mainView.addSubview(segmentedC5)

PlaygroundPage.current.liveView = mainView

Expand Down
111 changes: 69 additions & 42 deletions TTSegmentedControl.playground/Sources/TTSegmentedControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,30 @@

import UIKit


@IBDesignable
open class TTSegmentedControl: UIView {

//Version: 0.4.10
//Configure the options to for a custom design
@IBInspectable open var defaultTextFont: UIFont = UIFont.helveticaNeueLight(12)
@IBInspectable open var selectedTextFont: UIFont = UIFont.helveticaNeueLight(12)
@IBInspectable open var defaultTextColor: UIColor = UIColor.black
@IBInspectable open var selectedTextColor: UIColor = UIColor.white
@IBInspectable open var useGradient: Bool = true
@IBInspectable open var useHorizontalGradient: Bool = false {
didSet {
if useHorizontalGradient {
useVerticalGradient = false
}
}
}

@IBInspectable open var useVerticalGradient: Bool = true {
didSet {
if useVerticalGradient {
useHorizontalGradient = false
}
}
}

@IBInspectable open var containerBackgroundColor: UIColor = TTSegmentedControl.UIColorFromRGB(0xF4F4F4)
@IBInspectable open var thumbColor: UIColor = UIColor.clear
Expand Down Expand Up @@ -65,7 +79,7 @@ open class TTSegmentedControl: UIView {
fileprivate var thumbView = UIView()
fileprivate var selectedLabelsView = UIView()

fileprivate var isConfigurated = false
fileprivate var isConfigured = false
fileprivate var lastPointX: CGFloat = 0
fileprivate var originalCenter = CGPoint.zero
fileprivate var lastSelectedViewWidth: CGFloat = 0
Expand All @@ -79,7 +93,11 @@ open class TTSegmentedControl: UIView {
fileprivate var allowToChangeThumb = false
fileprivate var allowMove = true
fileprivate var selectInitialItem = 0
fileprivate var currentSelectedIndex = 0
fileprivate var _currentIndex: Int = 0

open var currentIndex: Int {
return _currentIndex
}

open var noItemSelected:Bool = false {
didSet {
Expand All @@ -100,32 +118,48 @@ open class TTSegmentedControl: UIView {
super.init(coder: aDecoder)
}

open func reconfigure() {
self.isConfigured = false
allItemLabels = []
allSelectedItemLabels = []
self.containerView.removeFromSuperview()
self.thumbContainerView.removeFromSuperview()
self.thumbView.removeFromSuperview()
self.selectedLabelsView.removeFromSuperview()

self.thumbContainerView = UIView()
self.thumbView = UIView()
self.selectedLabelsView = UIView()
self.containerView = UIView()
self.layoutSubviews()
}

open override func layoutSubviews() {
super.layoutSubviews()

if !isConfigurated {
if !isConfigured {
configureItemsConent()
configureViewBounds()

configureContainerView()
configureItems()
configureSelectedView()
configureSelectedLabelsView()
configureSelectedLabelItems()

isConfigurated = true
isConfigured = true
}

containerView.frame = bounds
containerView.layer.cornerRadius = cornerRadius < 0 ? 0.5 * containerView.frame.size.height : cornerRadius
selectedLabelsView.frame = containerView.bounds

updateFrameForLables(allItemLabels)
updateFrameForLables(allSelectedItemLabels)
updateFrameForLabels(allItemLabels)
updateFrameForLabels(allSelectedItemLabels)
updateSelectedViewFrame()

selectItemAt(index:currentSelectedIndex)
if !noItemSelected {
selectItemAt(index: _currentIndex)
}

_ = self.subviews.map({$0.isExclusiveTouch = true})

}
Expand All @@ -150,9 +184,7 @@ open class TTSegmentedControl: UIView {
return 100
}

fileprivate var isSwitch: Bool {
return attributedDefaultTitles.count == 2
}
open var isSwitch: Bool = false

//MARK: - Helpers
static public func UIColorFromRGB(_ rgbValue: UInt) -> UIColor {
Expand Down Expand Up @@ -226,9 +258,9 @@ extension TTSegmentedControl {
thumbContainerView.layer.insertSublayer(shadowLayer, at: 0)
}

if thumbGradientColors != nil && self.useGradient {
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
if thumbGradientColors != nil && (useHorizontalGradient || useVerticalGradient) {
gradientLayer.startPoint = useVerticalGradient ? CGPoint(x: 0.5, y: 0.0) : CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = useVerticalGradient ? CGPoint(x: 0.5, y: 1.0) : CGPoint(x: 1.0, y: 0.5)
gradientLayer.backgroundColor = thumbColor.cgColor
gradientLayer.colors = thumbGradientColors!.map({$0.cgColor})
thumbView.backgroundColor = UIColor.clear
Expand Down Expand Up @@ -326,7 +358,7 @@ extension TTSegmentedControl {
}
}

fileprivate func updateFrameForLables(_ allLabels: [UILabel]) {
fileprivate func updateFrameForLabels(_ allLabels: [UILabel]) {
let itemWidth = sectionWidth
var totalLabelWidth: CGFloat = 0
for label in allLabels {
Expand Down Expand Up @@ -433,7 +465,7 @@ extension TTSegmentedControl {

let index = label.tag
let title = label.text
self.currentSelectedIndex = index
self._currentIndex = index

didSelectItemWith?(index, title)
if title == nil {
Expand Down Expand Up @@ -479,10 +511,8 @@ extension TTSegmentedControl {
}

fileprivate func changeThumbFrameForPoint(_ point: CGPoint, animated: Bool) {

selectedLabelsView.isHidden = false
thumbView.isHidden = false

noItemSelected = false

lastPointX = point.x
let label = labelForPoint(point)
let center = label.center
Expand Down Expand Up @@ -638,27 +668,24 @@ extension TTSegmentedControl {

extension TTSegmentedControl {

open var currentIndex: Int {
if !isConfigurated {
return 0
}
let label = labelForPoint(thumbContainerView.center)
let index = allItemLabels.firstIndex(of: label)
return index ?? 0
}

public func selectItemAt(index: Int, animated: Bool = false) {
if !isConfigurated {
currentSelectedIndex = index
guard (index >= 0 && index < itemTitles.count) else {
print("[TTSegmentedControl]: Index \(index) is out of range.")
return
}
let label = allItemLabels[min(index, attributedDefaultTitles.count)]
selectedLabelsView.isHidden = noItemSelected

_currentIndex = index

guard isConfigured else {
return
}

let label = allItemLabels[index]
changeThumbFrameForPoint(label.center, animated: animated)
}

open func changeTitle(_ title: String, atIndex: Int) {
if !isConfigurated {
if !isConfigured {
return
}

Expand Down Expand Up @@ -691,7 +718,7 @@ extension TTSegmentedControl {
}

open func changeAttributedTitle(_ title: NSAttributedString, selectedTile: NSAttributedString?, atIndex: Int) {
if !isConfigurated {
if !isConfigured {
return
}

Expand Down Expand Up @@ -724,7 +751,7 @@ extension TTSegmentedControl {
}

open func titleForItemAtIndex(_ index: Int) -> String {
if !isConfigurated {
if !isConfigured {
return ""
}

Expand All @@ -736,23 +763,23 @@ extension TTSegmentedControl {
}

open func changeThumbShadowColor(_ color: UIColor) {
if !isConfigurated {
if !isConfigured {
return
}
thumbShadowColor = color
shadowLayer.shadowColor = color.cgColor
}

open func changeThumbColor(_ color: UIColor) {
if !isConfigurated {
if !isConfigured {
return
}
thumbColor = color
thumbView.backgroundColor = color
}

open func changeBackgroundColor(_ color: UIColor) {
if !isConfigurated {
if !isConfigured {
return
}
containerBackgroundColor = color
Expand Down
6 changes: 6 additions & 0 deletions TTSegmentedControl.playground/timeline.xctimeline
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>
2 changes: 1 addition & 1 deletion TTSegmentedControl.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Pod::Spec.new do |s|

# 1
s.platform = :ios
s.ios.deployment_target = '8.0'
s.ios.deployment_target = '15.0'
s.license = 'MIT'
s.name = "TTSegmentedControl"
s.summary = "An elegant, animated and customizable segmented control for iOS."
Expand Down
24 changes: 19 additions & 5 deletions TTSegmentedControl/TTSegmentedControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,21 @@ open class TTSegmentedControl: UIView {
@IBInspectable open var selectedTextFont: UIFont = UIFont.helveticaNeueLight(12)
@IBInspectable open var defaultTextColor: UIColor = UIColor.black
@IBInspectable open var selectedTextColor: UIColor = UIColor.white
@IBInspectable open var useGradient: Bool = true
@IBInspectable open var useHorizontalGradient: Bool = false {
didSet {
if useHorizontalGradient {
useVerticalGradient = false
}
}
}

@IBInspectable open var useVerticalGradient: Bool = true {
didSet {
if useVerticalGradient {
useHorizontalGradient = false
}
}
}

@IBInspectable open var containerBackgroundColor: UIColor = TTSegmentedControl.UIColorFromRGB(0xF4F4F4)
@IBInspectable open var thumbColor: UIColor = UIColor.clear
Expand Down Expand Up @@ -245,9 +259,9 @@ extension TTSegmentedControl {
thumbContainerView.layer.insertSublayer(shadowLayer, at: 0)
}

if thumbGradientColors != nil && self.useGradient {
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
if thumbGradientColors != nil && (useHorizontalGradient || useVerticalGradient) {
gradientLayer.startPoint = useVerticalGradient ? CGPoint(x: 0.5, y: 0.0) : CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = useVerticalGradient ? CGPoint(x: 0.5, y: 1.0) : CGPoint(x: 1.0, y: 0.5)
gradientLayer.backgroundColor = thumbColor.cgColor
gradientLayer.colors = thumbGradientColors!.map({$0.cgColor})
thumbView.backgroundColor = UIColor.clear
Expand Down Expand Up @@ -357,7 +371,7 @@ extension TTSegmentedControl {
for label in allLabels {

label.frame.origin.y = 0
label.frame.size.width = min(label.frame.size.width, itemWidth)
label.frame.size.width = itemWidth
label.frame.size.height = self.frame.size.height
label.frame.origin.x = (sectionWidth - label.frame.size.width)/2 + i * itemWidth
i += 1
Expand Down