Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f9194ec712 | |||
| 54e24f1053 | |||
| 2385466f70 | |||
| ab6a4fd165 | |||
| 5fe36abfe2 |
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'KDCircularProgress'
|
||||
s.version = '1.1'
|
||||
s.version = '1.3'
|
||||
s.license = 'MIT'
|
||||
s.summary = 'A circular progress view with gradients written in Swift'
|
||||
s.homepage = 'https://github.com/kaandedeoglu/KDCircularProgress'
|
||||
@@ -11,4 +11,4 @@ Pod::Spec.new do |s|
|
||||
|
||||
s.source_files = 'KDCircularProgress/*.swift'
|
||||
s.requires_arc = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -188,6 +188,11 @@ public class KDCircularProgress: UIView {
|
||||
return KDCircularProgressViewLayer.self
|
||||
}
|
||||
|
||||
public override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
radius = (frame.size.width/2.0) * 0.8
|
||||
}
|
||||
|
||||
private func setInitialValues() {
|
||||
radius = (frame.size.width/2.0) * 0.8 //We always apply a 20% padding, stopping glows from being clipped
|
||||
backgroundColor = .clearColor()
|
||||
@@ -223,15 +228,24 @@ public class KDCircularProgress: UIView {
|
||||
progressLayer.setNeedsDisplay()
|
||||
}
|
||||
|
||||
public func animateFromAngle(fromAngle: Int, toAngle: Int, duration: NSTimeInterval, completion: ((Bool) -> Void)?) {
|
||||
public func animateFromAngle(fromAngle: Int, toAngle: Int, duration: NSTimeInterval, relativeDuration: Bool = true, completion: ((Bool) -> Void)?) {
|
||||
if isAnimating() {
|
||||
pauseAnimation()
|
||||
}
|
||||
|
||||
let animationDuration: NSTimeInterval
|
||||
if relativeDuration {
|
||||
animationDuration = duration
|
||||
} else {
|
||||
let traveledAngle = UtilityFunctions.Mod(toAngle - fromAngle, range: 360, minMax: (0, 360))
|
||||
let scaledDuration = (NSTimeInterval(traveledAngle) * duration) / 360
|
||||
animationDuration = scaledDuration
|
||||
}
|
||||
|
||||
let animation = CABasicAnimation(keyPath: "angle")
|
||||
animation.fromValue = fromAngle
|
||||
animation.toValue = toAngle
|
||||
animation.duration = duration
|
||||
animation.duration = animationDuration
|
||||
animation.delegate = self
|
||||
angle = toAngle
|
||||
animationCompletionBlock = completion
|
||||
@@ -239,11 +253,11 @@ public class KDCircularProgress: UIView {
|
||||
progressLayer.addAnimation(animation, forKey: "angle")
|
||||
}
|
||||
|
||||
public func animateToAngle(toAngle: Int, duration: NSTimeInterval, completion: ((Bool) -> Void)?) {
|
||||
public func animateToAngle(toAngle: Int, duration: NSTimeInterval, relativeDuration: Bool = true, completion: ((Bool) -> Void)?) {
|
||||
if isAnimating() {
|
||||
pauseAnimation()
|
||||
}
|
||||
animateFromAngle(angle, toAngle: toAngle, duration: duration, completion: completion)
|
||||
animateFromAngle(angle, toAngle: toAngle, duration: duration, relativeDuration: relativeDuration, completion: completion)
|
||||
}
|
||||
|
||||
public func pauseAnimation() {
|
||||
@@ -291,11 +305,25 @@ public class KDCircularProgress: UIView {
|
||||
|
||||
private class KDCircularProgressViewLayer: CALayer {
|
||||
@NSManaged var angle: Int
|
||||
var radius: CGFloat!
|
||||
var radius: CGFloat! {
|
||||
didSet {
|
||||
invalidateGradientCache()
|
||||
}
|
||||
}
|
||||
var startAngle: Int!
|
||||
var clockwise: Bool!
|
||||
var clockwise: Bool! {
|
||||
didSet {
|
||||
if clockwise != oldValue {
|
||||
invalidateGradientCache()
|
||||
}
|
||||
}
|
||||
}
|
||||
var roundedCorners: Bool!
|
||||
var gradientRotateSpeed: CGFloat!
|
||||
var gradientRotateSpeed: CGFloat! {
|
||||
didSet {
|
||||
invalidateGradientCache()
|
||||
}
|
||||
}
|
||||
var glowAmount: CGFloat!
|
||||
var glowMode: KDCircularProgressGlowMode!
|
||||
var progressThickness: CGFloat!
|
||||
@@ -304,15 +332,14 @@ public class KDCircularProgress: UIView {
|
||||
var progressInsideFillColor: UIColor = UIColor.clearColor()
|
||||
var colorsArray: [UIColor]! {
|
||||
didSet {
|
||||
gradientCache = nil
|
||||
locationsCache = nil
|
||||
invalidateGradientCache()
|
||||
}
|
||||
}
|
||||
var gradientCache: CGGradientRef?
|
||||
var locationsCache: [CGFloat]?
|
||||
private var gradientCache: CGGradientRef?
|
||||
private var locationsCache: [CGFloat]?
|
||||
|
||||
struct GlowConstants {
|
||||
static let sizeToGlowRatio: CGFloat = 0.00015
|
||||
private struct GlowConstants {
|
||||
private static let sizeToGlowRatio: CGFloat = 0.00015
|
||||
static func glowAmountForAngle(angle: Int, glowAmount: CGFloat, glowMode: KDCircularProgressGlowMode, size: CGFloat) -> CGFloat {
|
||||
switch glowMode {
|
||||
case .Forward:
|
||||
@@ -421,12 +448,12 @@ public class KDCircularProgress: UIView {
|
||||
UIGraphicsPopContext()
|
||||
}
|
||||
|
||||
func fillRectWithContext(ctx: CGContext!, color: UIColor) {
|
||||
private func fillRectWithContext(ctx: CGContext!, color: UIColor) {
|
||||
CGContextSetFillColorWithColor(ctx, color.CGColor)
|
||||
CGContextFillRect(ctx, bounds)
|
||||
}
|
||||
|
||||
func drawGradientWithContext(ctx: CGContext!, componentsArray: [CGFloat]) {
|
||||
private func drawGradientWithContext(ctx: CGContext!, componentsArray: [CGFloat]) {
|
||||
let baseSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let locations = locationsCache ?? gradientLocationsFromColorCount(componentsArray.count/4, gradientWidth: bounds.size.width)
|
||||
let gradient: CGGradient
|
||||
@@ -434,9 +461,9 @@ public class KDCircularProgress: UIView {
|
||||
if let g = self.gradientCache {
|
||||
gradient = g
|
||||
} else {
|
||||
let g = CGGradientCreateWithColorComponents(baseSpace, componentsArray, locations,componentsArray.count / 4)
|
||||
guard let g = CGGradientCreateWithColorComponents(baseSpace, componentsArray, locations,componentsArray.count / 4) else { return }
|
||||
self.gradientCache = g
|
||||
gradient = g!
|
||||
gradient = g
|
||||
}
|
||||
|
||||
let halfX = bounds.size.width/2.0
|
||||
@@ -451,7 +478,7 @@ public class KDCircularProgress: UIView {
|
||||
CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, .DrawsBeforeStartLocation)
|
||||
}
|
||||
|
||||
func gradientLocationsFromColorCount(colorCount: Int, gradientWidth: CGFloat) -> [CGFloat] {
|
||||
private func gradientLocationsFromColorCount(colorCount: Int, gradientWidth: CGFloat) -> [CGFloat] {
|
||||
if colorCount == 0 || gradientWidth == 0 {
|
||||
return []
|
||||
} else {
|
||||
@@ -469,5 +496,10 @@ public class KDCircularProgress: UIView {
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
private func invalidateGradientCache() {
|
||||
gradientCache = nil
|
||||
locationsCache = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A279b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="vXZ-lx-hvc">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="vXZ-lx-hvc">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
|
||||
@@ -35,7 +35,7 @@ class ViewController: UIViewController {
|
||||
}
|
||||
|
||||
@IBAction func animateButtonTapped(sender: UIButton) {
|
||||
progress.animateToAngle(360, duration: 5) { completed in
|
||||
progress.animateFromAngle(0, toAngle: 360, duration: 5) { completed in
|
||||
if completed {
|
||||
print("animation stopped, completed")
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user