From 33e38bbee5424e2d6fc4f28d7f7905590373a4c2 Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Sat, 16 Apr 2016 22:35:06 +0200 Subject: [PATCH 1/8] allow UIImage as thumb image --- Pod/Classes/CircleSlider.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Pod/Classes/CircleSlider.swift b/Pod/Classes/CircleSlider.swift index c24f542..b5832db 100644 --- a/Pod/Classes/CircleSlider.swift +++ b/Pod/Classes/CircleSlider.swift @@ -13,6 +13,7 @@ public enum CircleSliderOption { case ThumbColor(UIColor) case BarWidth(CGFloat) case ThumbWidth(CGFloat) + case ThumbImage(UIImage?) case MaxValue(Float) case MinValue(Float) case SliderEnabled(Bool) @@ -37,6 +38,14 @@ public class CircleSlider: UIControl { self.layer.addSublayer(self.trackLayer) } } + private var thumbImageView: UIImageView! { + didSet { + if self.sliderEnabled && self.thumbImage != nil { + self.thumbImageView.image = self.thumbImage + self.addSubview(self.thumbImageView) + } + } + } private var thumbView: UIView! { didSet { if self.sliderEnabled { @@ -54,6 +63,7 @@ public class CircleSlider: UIControl { private var barColor = UIColor.lightGrayColor() private var trackingColor = UIColor.blueColor() private var thumbColor = UIColor.blackColor() + private var thumbImage: UIImage? private var barWidth: CGFloat = 20 private var maxValue: Float = 100 private var minValue: Float = 0 @@ -94,6 +104,9 @@ public class CircleSlider: UIControl { if self.thumbView == nil { self.thumbView = UIView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) } + if self.thumbImageView == nil { + self.thumbImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) + } } override public func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { @@ -125,6 +138,8 @@ public class CircleSlider: UIControl { self.trackLayer = TrackLayer(bounds: self.bounds, setting: self.createLayerSetting()) self.thumbView.removeFromSuperview() self.thumbView = UIView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) + self.thumbImageView.removeFromSuperview() + self.thumbImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) self.layout(self.latestDegree) } @@ -151,6 +166,8 @@ public class CircleSlider: UIControl { self._value = self.minValue case let .SliderEnabled(value): self.sliderEnabled = value + case let .ThumbImage(value): + self.thumbImage = value } } // Adjust because value not rise up to the maxValue @@ -161,6 +178,7 @@ public class CircleSlider: UIControl { if let trackLayer = self.trackLayer, thumbView = self.thumbView { trackLayer.degree = degree thumbView.center = self.thumbCenter(degree) + thumbImageView.center = self.thumbCenter(degree) trackLayer.setNeedsDisplay() } } From f17eb28dc2842d982de9e1db9165c1d661c29f33 Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Sat, 16 Apr 2016 22:41:16 +0200 Subject: [PATCH 2/8] podspec updated --- CircleSlider.podspec | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/CircleSlider.podspec b/CircleSlider.podspec index 959c2e9..149e667 100644 --- a/CircleSlider.podspec +++ b/CircleSlider.podspec @@ -1,15 +1,13 @@ Pod::Spec.new do |s| s.name = "CircleSlider" -s.version = "0.2.0" +s.version = "0.2.1" s.summary = "CircleSlider is a Circular slider library. written in pure swift." -s.homepage = "https://github.com/shushutochako/CircleSlider" +s.homepage = "https://github.com/lampi87/CircleSlider.git" s.license = 'MIT' -s.author = { "shushutochako" => "shushutochako22@gmail.com" } -s.source = { :git => "https://github.com/shushutochako/CircleSlider.git", :tag => s.version.to_s } -s.social_media_url = 'https://twitter.com/shushutochako' +s.source = { :git => "https://github.com/lampi87/CircleSlider.git", :tag => s.version.to_s } s.platform = :ios, '8.0' s.requires_arc = true s.source_files = 'Pod/Classes/**/*' -end \ No newline at end of file +end From a5c251c52226215cfb33a58773538eb0e26c464f Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Sat, 16 Apr 2016 22:43:48 +0200 Subject: [PATCH 3/8] readme updated --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b556e9f..a80a3a8 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ self.circleSlider.changeOptions([.BarWidth(45)]) - ``case ThumbColor(UIColor)`` - ``case BarWidth(CGFloat)`` - ``case ThumbWidth(CGFloat)`` +- ``case ThumbImage(UImage?)`` - ``case MaxValue(Float)`` - ``case MinValue(Float)`` - ``case SliderEnabled(Bool) `` From ede80ff5f65db2ace1c7cdb78bf3ac7481c4c0ec Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Sat, 16 Apr 2016 22:44:24 +0200 Subject: [PATCH 4/8] readme updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a80a3a8..ca4004e 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ self.circleSlider.changeOptions([.BarWidth(45)]) - ``case ThumbColor(UIColor)`` - ``case BarWidth(CGFloat)`` - ``case ThumbWidth(CGFloat)`` -- ``case ThumbImage(UImage?)`` +- ``case ThumbImage(UIImage?)`` - ``case MaxValue(Float)`` - ``case MinValue(Float)`` - ``case SliderEnabled(Bool) `` From 5f3059235a14d41669afcb2a1a8224663421e423 Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Sat, 14 May 2016 23:54:44 +0200 Subject: [PATCH 5/8] offset enabled --- Pod/Classes/CircleSlider.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Pod/Classes/CircleSlider.swift b/Pod/Classes/CircleSlider.swift index b5832db..01314c0 100644 --- a/Pod/Classes/CircleSlider.swift +++ b/Pod/Classes/CircleSlider.swift @@ -17,6 +17,7 @@ public enum CircleSliderOption { case MaxValue(Float) case MinValue(Float) case SliderEnabled(Bool) + case ThumbOffset(Bool) } public class CircleSlider: UIControl { @@ -68,6 +69,7 @@ public class CircleSlider: UIControl { private var maxValue: Float = 100 private var minValue: Float = 0 private var sliderEnabled = true + private var thumbOffset = true private var _thumbWidth: CGFloat? private var thumbWidth: CGFloat { get { @@ -168,6 +170,8 @@ public class CircleSlider: UIControl { self.sliderEnabled = value case let .ThumbImage(value): self.thumbImage = value + case let .ThumbOffset(value): + self.thumbOffset = value } } // Adjust because value not rise up to the maxValue @@ -193,7 +197,10 @@ public class CircleSlider: UIControl { } private func thumbCenter(degree: Double) -> CGPoint { - let radius = (self.bounds.width * 0.5) - (self.barWidth * 0.5) + var radius = (self.bounds.width * 0.5) + if thumbOffset { + radius = radius - (self.barWidth * 0.5) + } return Math.pointFromAngle(self.frame, angle: degree, radius: Double(radius)) } } From e23e9618112829091eefc46f0dd09465a93bdf52 Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Sun, 15 May 2016 00:00:08 +0200 Subject: [PATCH 6/8] version number ingrement --- CircleSlider.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CircleSlider.podspec b/CircleSlider.podspec index 149e667..2fb2317 100644 --- a/CircleSlider.podspec +++ b/CircleSlider.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "CircleSlider" -s.version = "0.2.1" +s.version = "0.2.2" s.summary = "CircleSlider is a Circular slider library. written in pure swift." s.homepage = "https://github.com/lampi87/CircleSlider.git" s.license = 'MIT' From 8caada95a2b74c6aea4d0ba110521232268cccf7 Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Sun, 15 May 2016 12:44:08 +0200 Subject: [PATCH 7/8] author added --- CircleSlider.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CircleSlider.podspec b/CircleSlider.podspec index 2fb2317..4432532 100644 --- a/CircleSlider.podspec +++ b/CircleSlider.podspec @@ -5,7 +5,7 @@ s.summary = "CircleSlider is a Circular slider library. written in pure s.homepage = "https://github.com/lampi87/CircleSlider.git" s.license = 'MIT' s.source = { :git => "https://github.com/lampi87/CircleSlider.git", :tag => s.version.to_s } - +s.author = { "shushutochako" => "shushutochako22@gmail.com" } s.platform = :ios, '8.0' s.requires_arc = true From 618babe4155030f9ce45a53e8977c25cc69a0ca6 Mon Sep 17 00:00:00 2001 From: Alexander Lampret Date: Mon, 16 May 2016 20:46:29 +0200 Subject: [PATCH 8/8] deprecated parts fixed --- CircleSlider.podspec | 2 +- Pod/Classes/CircleSlider.swift | 364 ++++++++++++++++----------------- Pod/Classes/Math.swift | 82 ++++---- Pod/Classes/TrackLayer.swift | 130 ++++++------ 4 files changed, 289 insertions(+), 289 deletions(-) diff --git a/CircleSlider.podspec b/CircleSlider.podspec index 4432532..548a957 100644 --- a/CircleSlider.podspec +++ b/CircleSlider.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "CircleSlider" -s.version = "0.2.2" +s.version = "0.2.3" s.summary = "CircleSlider is a Circular slider library. written in pure swift." s.homepage = "https://github.com/lampi87/CircleSlider.git" s.license = 'MIT' diff --git a/Pod/Classes/CircleSlider.swift b/Pod/Classes/CircleSlider.swift index 01314c0..ea2f2f1 100644 --- a/Pod/Classes/CircleSlider.swift +++ b/Pod/Classes/CircleSlider.swift @@ -7,38 +7,38 @@ // public enum CircleSliderOption { - case StartAngle(Double) - case BarColor(UIColor) - case TrackingColor(UIColor) - case ThumbColor(UIColor) - case BarWidth(CGFloat) - case ThumbWidth(CGFloat) - case ThumbImage(UIImage?) - case MaxValue(Float) - case MinValue(Float) - case SliderEnabled(Bool) - case ThumbOffset(Bool) + case StartAngle(Double) + case BarColor(UIColor) + case TrackingColor(UIColor) + case ThumbColor(UIColor) + case BarWidth(CGFloat) + case ThumbWidth(CGFloat) + case ThumbImage(UIImage?) + case MaxValue(Float) + case MinValue(Float) + case SliderEnabled(Bool) + case ThumbOffset(Bool) } public class CircleSlider: UIControl { - private var latestDegree: Double = 0 - private var _value: Float = 0 - public var value: Float { - get { - return self._value - } - set { - self._value = newValue - self.sendActionsForControlEvents(.ValueChanged) - let degree = Math.degreeFromValue(self.startAngle, value: self.value, maxValue: self.maxValue, minValue: self.minValue) - self.layout(degree) - } - } - private var trackLayer: TrackLayer! { - didSet { - self.layer.addSublayer(self.trackLayer) - } - } + private var latestDegree: Double = 0 + private var _value: Float = 0 + public var value: Float { + get { + return self._value + } + set { + self._value = newValue + self.sendActionsForControlEvents(.ValueChanged) + let degree = Math.degreeFromValue(self.startAngle, value: self.value, maxValue: self.maxValue, minValue: self.minValue) + self.layout(degree) + } + } + private var trackLayer: TrackLayer! { + didSet { + self.layer.addSublayer(self.trackLayer) + } + } private var thumbImageView: UIImageView! { didSet { if self.sliderEnabled && self.thumbImage != nil { @@ -47,160 +47,160 @@ public class CircleSlider: UIControl { } } } - private var thumbView: UIView! { - didSet { - if self.sliderEnabled { - self.thumbView.backgroundColor = self.thumbColor - self.thumbView.center = self.thumbCenter(self.startAngle) - self.thumbView.layer.cornerRadius = self.thumbView!.bounds.size.width * 0.5 - self.addSubview(self.thumbView) - } else { - self.thumbView.hidden = true - } - } - } - // Options - private var startAngle: Double = -90 - private var barColor = UIColor.lightGrayColor() - private var trackingColor = UIColor.blueColor() - private var thumbColor = UIColor.blackColor() - private var thumbImage: UIImage? - private var barWidth: CGFloat = 20 - private var maxValue: Float = 100 - private var minValue: Float = 0 - private var sliderEnabled = true - private var thumbOffset = true - private var _thumbWidth: CGFloat? - private var thumbWidth: CGFloat { - get { - if let retValue = self._thumbWidth { - return retValue - } - return self.barWidth * 1.5 - } - set { - self._thumbWidth = newValue - } - } - - override public func awakeFromNib() { - super.awakeFromNib() - self.backgroundColor = UIColor.clearColor() - } - - public init(frame: CGRect, options: [CircleSliderOption]?) { - super.init(frame: frame) - if let options = options { - self.build(options) - } - } - - required public init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func layoutSublayersOfLayer(layer: CALayer) { - if self.trackLayer == nil { - self.trackLayer = TrackLayer(bounds: self.bounds, setting: self.createLayerSetting()) - } - if self.thumbView == nil { - self.thumbView = UIView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) - } - if self.thumbImageView == nil { + private var thumbView: UIView! { + didSet { + if self.sliderEnabled { + self.thumbView.backgroundColor = self.thumbColor + self.thumbView.center = self.thumbCenter(self.startAngle) + self.thumbView.layer.cornerRadius = self.thumbView!.bounds.size.width * 0.5 + self.addSubview(self.thumbView) + } else { + self.thumbView.hidden = true + } + } + } + // Options + private var startAngle: Double = -90 + private var barColor = UIColor.lightGrayColor() + private var trackingColor = UIColor.blueColor() + private var thumbColor = UIColor.blackColor() + private var thumbImage: UIImage? + private var barWidth: CGFloat = 20 + private var maxValue: Float = 100 + private var minValue: Float = 0 + private var sliderEnabled = true + private var thumbOffset = true + private var _thumbWidth: CGFloat? + private var thumbWidth: CGFloat { + get { + if let retValue = self._thumbWidth { + return retValue + } + return self.barWidth * 1.5 + } + set { + self._thumbWidth = newValue + } + } + + override public func awakeFromNib() { + super.awakeFromNib() + self.backgroundColor = UIColor.clearColor() + } + + public init(frame: CGRect, options: [CircleSliderOption]?) { + super.init(frame: frame) + if let options = options { + self.build(options) + } + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override public func layoutSublayersOfLayer(layer: CALayer) { + if self.trackLayer == nil { + self.trackLayer = TrackLayer(bounds: self.bounds, setting: self.createLayerSetting()) + } + if self.thumbView == nil { + self.thumbView = UIView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) + } + if self.thumbImageView == nil { + self.thumbImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) + } + } + + override public func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { + let rect = self.trackLayer.hollowRect + let hollowPath = UIBezierPath(roundedRect: rect, cornerRadius: self.trackLayer.hollowRadius) + if !(CGRectContainsPoint(self.bounds, point) || hollowPath.containsPoint(point)) || + !(CGRectContainsPoint(self.thumbView.frame, point)) { + return nil + } + return self + } + + override public func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { + let degree = Math.pointPairToBearingDegrees(self.center, endPoint: touch.locationInView(self)) + self.latestDegree = degree + self.layout(degree) + let value = Float(Math.adjustValue(self.startAngle, degree: degree, maxValue: self.maxValue, minValue: self.minValue)) + self.value = value + return true + } + + public func changeOptions(options: [CircleSliderOption]) { + self.build(options) + self.redraw() + } + + private func redraw() { + self.trackLayer.removeFromSuperlayer() + self.trackLayer = TrackLayer(bounds: self.bounds, setting: self.createLayerSetting()) + self.thumbView.removeFromSuperview() + self.thumbView = UIView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) + self.thumbImageView.removeFromSuperview() self.thumbImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) + self.layout(self.latestDegree) } - } - - override public func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { - let rect = self.trackLayer.hollowRect - let hollowPath = UIBezierPath(roundedRect: rect, cornerRadius: self.trackLayer.hollowRadius) - if !(CGRectContainsPoint(self.bounds, point) || hollowPath.containsPoint(point)) || - !(CGRectContainsPoint(self.thumbView.frame, point)) { - return nil - } - return self - } - - override public func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { - let degree = Math.pointPairToBearingDegrees(self.center, endPoint: touch.locationInView(self)) - self.latestDegree = degree - self.layout(degree) - let value = Float(Math.adjustValue(self.startAngle, degree: degree, maxValue: self.maxValue, minValue: self.minValue)) - self.value = value - return true - } - - public func changeOptions(options: [CircleSliderOption]) { - self.build(options) - self.redraw() - } - - private func redraw() { - self.trackLayer.removeFromSuperlayer() - self.trackLayer = TrackLayer(bounds: self.bounds, setting: self.createLayerSetting()) - self.thumbView.removeFromSuperview() - self.thumbView = UIView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) - self.thumbImageView.removeFromSuperview() - self.thumbImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.thumbWidth, height: self.thumbWidth)) - self.layout(self.latestDegree) - } - private func build(options: [CircleSliderOption]) { - for option in options { - switch option { - case let .StartAngle(value): - self.startAngle = value - self.latestDegree = self.startAngle - case let .BarColor(value): - self.barColor = value - case let .TrackingColor(value): - self.trackingColor = value - case let .ThumbColor(value): - self.thumbColor = value - case let .BarWidth(value): - self.barWidth = value - case let .ThumbWidth(value): - self.thumbWidth = value - case let .MaxValue(value): - self.maxValue = value - case let .MinValue(value): - self.minValue = value - self._value = self.minValue - case let .SliderEnabled(value): - self.sliderEnabled = value - case let .ThumbImage(value): - self.thumbImage = value - case let .ThumbOffset(value): - self.thumbOffset = value - } - } - // Adjust because value not rise up to the maxValue - self.maxValue++ - } - - private func layout(degree: Double) { - if let trackLayer = self.trackLayer, thumbView = self.thumbView { - trackLayer.degree = degree - thumbView.center = self.thumbCenter(degree) - thumbImageView.center = self.thumbCenter(degree) - trackLayer.setNeedsDisplay() - } - } - - private func createLayerSetting() -> TrackLayer.Setting { - var setting = TrackLayer.Setting() - setting.startAngle = self.startAngle - setting.barColor = self.barColor - setting.trackingColor = self.trackingColor - setting.barWidth = self.barWidth - return setting - } - - private func thumbCenter(degree: Double) -> CGPoint { - var radius = (self.bounds.width * 0.5) - if thumbOffset { - radius = radius - (self.barWidth * 0.5) - } - return Math.pointFromAngle(self.frame, angle: degree, radius: Double(radius)) - } + private func build(options: [CircleSliderOption]) { + for option in options { + switch option { + case let .StartAngle(value): + self.startAngle = value + self.latestDegree = self.startAngle + case let .BarColor(value): + self.barColor = value + case let .TrackingColor(value): + self.trackingColor = value + case let .ThumbColor(value): + self.thumbColor = value + case let .BarWidth(value): + self.barWidth = value + case let .ThumbWidth(value): + self.thumbWidth = value + case let .MaxValue(value): + self.maxValue = value + case let .MinValue(value): + self.minValue = value + self._value = self.minValue + case let .SliderEnabled(value): + self.sliderEnabled = value + case let .ThumbImage(value): + self.thumbImage = value + case let .ThumbOffset(value): + self.thumbOffset = value + } + } + // Adjust because value not rise up to the maxValue + self.maxValue += 1 + } + + private func layout(degree: Double) { + if let trackLayer = self.trackLayer, thumbView = self.thumbView { + trackLayer.degree = degree + thumbView.center = self.thumbCenter(degree) + thumbImageView.center = self.thumbCenter(degree) + trackLayer.setNeedsDisplay() + } + } + + private func createLayerSetting() -> TrackLayer.Setting { + var setting = TrackLayer.Setting() + setting.startAngle = self.startAngle + setting.barColor = self.barColor + setting.trackingColor = self.trackingColor + setting.barWidth = self.barWidth + return setting + } + + private func thumbCenter(degree: Double) -> CGPoint { + var radius = (self.bounds.width * 0.5) + if thumbOffset { + radius = radius - (self.barWidth * 0.5) + } + return Math.pointFromAngle(self.frame, angle: degree, radius: Double(radius)) + } } diff --git a/Pod/Classes/Math.swift b/Pod/Classes/Math.swift index 1db3a01..c3af09b 100644 --- a/Pod/Classes/Math.swift +++ b/Pod/Classes/Math.swift @@ -9,46 +9,46 @@ import UIKit internal class Math { - - internal class func degreesToRadians(angle: Double) -> Double { - return angle / 180 * M_PI - } - - internal class func pointFromAngle(frame: CGRect, angle: Double, radius: Double) -> CGPoint { - let radian = self.degreesToRadians(angle) - let x = Double(CGRectGetMidX(frame)) + cos(radian) * radius - let y = Double(CGRectGetMidY(frame)) + sin(radian) * radius - return CGPoint(x: x, y: y) - } - - internal class func pointPairToBearingDegrees(startPoint: CGPoint, endPoint: CGPoint) -> Double { - let originPoint = CGPointMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y) - let bearingRadians = atan2(Double(originPoint.y), Double(originPoint.x)) - var bearingDegrees = bearingRadians * (180.0 / M_PI) - bearingDegrees = (bearingDegrees > 0.0 ? bearingDegrees : (360.0 + bearingDegrees)) - return bearingDegrees - } - - internal class func adjustValue(startAngle: Double, degree: Double, maxValue: Float, minValue: Float) -> Double { - let ratio = Double((maxValue - minValue) / 360) - let ratioStart = ratio * startAngle - let ratioDegree = ratio * degree - let adjustValue: Double - if startAngle < 0 { - adjustValue = (360 + startAngle) > degree ? (ratioDegree - ratioStart) : (ratioDegree - ratioStart) - (360 * ratio) - } else { - adjustValue = (360 - (360 - startAngle)) < degree ? (ratioDegree - ratioStart) : (ratioDegree - ratioStart) + (360 * ratio) + + internal class func degreesToRadians(angle: Double) -> Double { + return angle / 180 * M_PI + } + + internal class func pointFromAngle(frame: CGRect, angle: Double, radius: Double) -> CGPoint { + let radian = self.degreesToRadians(angle) + let x = Double(CGRectGetMidX(frame)) + cos(radian) * radius + let y = Double(CGRectGetMidY(frame)) + sin(radian) * radius + return CGPoint(x: x, y: y) + } + + internal class func pointPairToBearingDegrees(startPoint: CGPoint, endPoint: CGPoint) -> Double { + let originPoint = CGPointMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y) + let bearingRadians = atan2(Double(originPoint.y), Double(originPoint.x)) + var bearingDegrees = bearingRadians * (180.0 / M_PI) + bearingDegrees = (bearingDegrees > 0.0 ? bearingDegrees : (360.0 + bearingDegrees)) + return bearingDegrees + } + + internal class func adjustValue(startAngle: Double, degree: Double, maxValue: Float, minValue: Float) -> Double { + let ratio = Double((maxValue - minValue) / 360) + let ratioStart = ratio * startAngle + let ratioDegree = ratio * degree + let adjustValue: Double + if startAngle < 0 { + adjustValue = (360 + startAngle) > degree ? (ratioDegree - ratioStart) : (ratioDegree - ratioStart) - (360 * ratio) + } else { + adjustValue = (360 - (360 - startAngle)) < degree ? (ratioDegree - ratioStart) : (ratioDegree - ratioStart) + (360 * ratio) + } + return adjustValue + (Double(minValue)) + } + + internal class func adjustDegree(startAngle: Double, degree: Double) -> Double { + return (360 + startAngle) > degree ? degree : -(360 - degree) + } + + internal class func degreeFromValue(startAngle: Double, value: Float, maxValue: Float, minValue: Float) -> Double { + let ratio = Double((maxValue - minValue) / 360) + let angle = Double(value) / ratio + return angle + startAngle - (Double(minValue) / ratio) } - return adjustValue + (Double(minValue)) - } - - internal class func adjustDegree(startAngle: Double, degree: Double) -> Double { - return (360 + startAngle) > degree ? degree : -(360 - degree) - } - - internal class func degreeFromValue(startAngle: Double, value: Float, maxValue: Float, minValue: Float) -> Double { - let ratio = Double((maxValue - minValue) / 360) - let angle = Double(value) / ratio - return angle + startAngle - (Double(minValue) / ratio) - } } diff --git a/Pod/Classes/TrackLayer.swift b/Pod/Classes/TrackLayer.swift index fc4045c..b24f121 100644 --- a/Pod/Classes/TrackLayer.swift +++ b/Pod/Classes/TrackLayer.swift @@ -9,69 +9,69 @@ import UIKit internal class TrackLayer: CAShapeLayer { - struct Setting { - var startAngle = Double() - var barWidth = CGFloat() - var barColor = UIColor() - var trackingColor = UIColor() - } - internal var setting = Setting!() - internal var degree: Double = 0 - internal var hollowRadius: CGFloat { - return (self.bounds.width * 0.5) - self.setting.barWidth - } - internal var currentCenter: CGPoint { - return CGPoint(x: CGRectGetMidX(self.bounds), y: CGRectGetMidY(self.bounds)) - } - internal var hollowRect: CGRect { - return CGRect( - x: self.currentCenter.x - self.hollowRadius, - y: self.currentCenter.y - self.hollowRadius, - width: self.hollowRadius * 2.0, - height: self.hollowRadius * 2.0) - } - internal init(bounds: CGRect, setting: Setting) { - super.init() - self.bounds = bounds - self.setting = setting - self.cornerRadius = self.bounds.size.width * 0.5 - self.position = self.currentCenter - self.backgroundColor = self.setting.barColor.CGColor - self.mask() - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override internal func drawInContext(ctx: CGContext) { - self.drawTrack(ctx) - } - - private func mask() { - let maskLayer = CAShapeLayer() - maskLayer.bounds = self.bounds - let ovalRect = self.hollowRect - let path = UIBezierPath(ovalInRect: ovalRect) - path.appendPath(UIBezierPath(rect: maskLayer.bounds)) - maskLayer.path = path.CGPath - maskLayer.position = self.currentCenter - maskLayer.fillRule = kCAFillRuleEvenOdd - self.mask = maskLayer - } - - private func drawTrack(ctx: CGContext) { - let adjustDegree = Math.adjustDegree(self.setting.startAngle, degree: self.degree) - let centerX = self.currentCenter.x - let centerY = self.currentCenter.y - let radius = min(centerX, centerY) - CGContextSetFillColorWithColor(ctx, self.setting.trackingColor.CGColor) - CGContextBeginPath(ctx) - CGContextMoveToPoint(ctx, centerX, centerY) - CGContextAddArc(ctx, centerX, centerY, radius, - CGFloat(Math.degreesToRadians(self.setting.startAngle - M_PI * 0.5)), - CGFloat(Math.degreesToRadians(adjustDegree - M_PI * 0.5)), 0) - CGContextClosePath(ctx); - CGContextFillPath(ctx); - } + struct Setting { + var startAngle = Double() + var barWidth = CGFloat() + var barColor = UIColor() + var trackingColor = UIColor() + } + internal var setting: Setting! + internal var degree: Double = 0 + internal var hollowRadius: CGFloat { + return (self.bounds.width * 0.5) - self.setting.barWidth + } + internal var currentCenter: CGPoint { + return CGPoint(x: CGRectGetMidX(self.bounds), y: CGRectGetMidY(self.bounds)) + } + internal var hollowRect: CGRect { + return CGRect( + x: self.currentCenter.x - self.hollowRadius, + y: self.currentCenter.y - self.hollowRadius, + width: self.hollowRadius * 2.0, + height: self.hollowRadius * 2.0) + } + internal init(bounds: CGRect, setting: Setting) { + super.init() + self.bounds = bounds + self.setting = setting + self.cornerRadius = self.bounds.size.width * 0.5 + self.position = self.currentCenter + self.backgroundColor = self.setting.barColor.CGColor + self.mask() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override internal func drawInContext(ctx: CGContext) { + self.drawTrack(ctx) + } + + private func mask() { + let maskLayer = CAShapeLayer() + maskLayer.bounds = self.bounds + let ovalRect = self.hollowRect + let path = UIBezierPath(ovalInRect: ovalRect) + path.appendPath(UIBezierPath(rect: maskLayer.bounds)) + maskLayer.path = path.CGPath + maskLayer.position = self.currentCenter + maskLayer.fillRule = kCAFillRuleEvenOdd + self.mask = maskLayer + } + + private func drawTrack(ctx: CGContext) { + let adjustDegree = Math.adjustDegree(self.setting.startAngle, degree: self.degree) + let centerX = self.currentCenter.x + let centerY = self.currentCenter.y + let radius = min(centerX, centerY) + CGContextSetFillColorWithColor(ctx, self.setting.trackingColor.CGColor) + CGContextBeginPath(ctx) + CGContextMoveToPoint(ctx, centerX, centerY) + CGContextAddArc(ctx, centerX, centerY, radius, + CGFloat(Math.degreesToRadians(self.setting.startAngle - M_PI * 0.5)), + CGFloat(Math.degreesToRadians(adjustDegree - M_PI * 0.5)), 0) + CGContextClosePath(ctx); + CGContextFillPath(ctx); + } }