28 Commits

Author SHA1 Message Date
Kaan Dedeoglu f9194ec712 Add relativeDuration default value to animate methods to specify if the duration is global or specific to current angle 2015-11-11 13:52:04 +02:00
Kaan Dedeoglu 54e24f1053 Update podspec to 1.3 2015-10-16 03:38:16 +03:00
Kaan Dedeoglu 2385466f70 Update example animation call to restart it everytime the button is hit. 2015-10-16 03:37:19 +03:00
Kaan Dedeoglu ab6a4fd165 Some fixes for resizing behavior, invalidate gradient and gradient location caches when affecting properties change 2015-10-16 03:29:51 +03:00
Kaan Dedeoglu 5fe36abfe2 modify podspec for v1.2 2015-09-16 20:37:56 +03:00
Kaan Dedeoglu 466be89f6d Merge pull request #10 from kaandedeoglu/swift2.0
Swift2.0
2015-09-16 20:30:09 +03:00
Kaan Dedeoglu b9f8a3e46e Update README.md 2015-09-15 19:26:58 +03:00
Kaan Dedeoglu b9cdde76e5 Reorganize some properties, add description about progressInsideFillColor 2015-09-11 11:09:44 +03:00
Kaan Dedeoglu f7959fdd54 Add note about IBInspectable and IBDesignable support 2015-09-10 23:10:43 +03:00
Kaan Dedeoglu c01c9d9b59 Add progressInsideFillColor IBInspectable property 2015-09-10 23:06:37 +03:00
Kaan Dedeoglu 125bfcc5a4 Beta 7 fixes 2015-08-25 02:47:15 +03:00
Kaan Dedeoglu e823e29b2e Merge branch 'master' of https://github.com/kaandedeoglu/KDCircularProgress into swift2.0 2015-08-17 20:01:54 +03:00
Kaan Dedeoglu ee6a46abd3 Make IBOutletColor1-2-3 properties private. 2015-07-01 12:28:50 +03:00
Kaan Dedeoglu a90c94254e Swift 2.0 changes 2015-06-28 11:43:44 +03:00
Kaan Dedeoglu 9fb2796b70 Update README.md 2015-06-25 17:38:31 +03:00
Kaan Dedeoglu 58cbb4a4a6 Update Podspec, push 1.1 to pods 2015-06-25 17:35:14 +03:00
Kaan Dedeoglu e444b0949d Merge pull request #6 from kaandedeoglu/feature/IBInspectable_IBDesignable
Added IBInspectable / IBDesignable support. Added another progress fr…
2015-06-25 17:31:17 +03:00
Kaan Dedeoglu 84851e6225 Added IBInspectable / IBDesignable support. Added another progress from the Storyboard with Autolayout constraints. 2015-06-25 17:30:45 +03:00
Kaan Dedeoglu 0ebaa7657c Merge pull request #5 from andrewcbancroft/implement-init-coder
Implemented init(coder:)
2015-06-25 16:05:10 +03:00
Andrew Bancroft c11544bd76 Implemented init(coder:) 2015-06-24 21:46:57 -05:00
Kaan Dedeoglu ede9f5195c Merge pull request #3 from olucurious/master
Add a stopAnimation method
2015-06-22 19:42:47 +03:00
olucurious 3f6ce74676 Merge pull request #2 from olucurious/olucurious-patch-2
Update KDCircularProgress.swift
2015-06-22 16:42:51 +01:00
olucurious 215c4cf506 Update KDCircularProgress.swift
Added a stopAnimation method and I used 0 as the angle instead of the weird 360 which does basically the same thing.
2015-06-22 16:40:33 +01:00
olucurious a7d667140c Merge pull request #1 from olucurious/olucurious-patch-1-1
Update KDCircularProgress.swift
2015-06-21 18:24:29 +01:00
olucurious 26a2f77f73 Update KDCircularProgress.swift
Added a stopAnimation() method
2015-06-21 18:23:54 +01:00
Kaan Dedeoglu 67a0515ad9 Merge pull request #1 from justwudi/master
Fix optional unwrap error when calling removeFromSuperview
2015-06-16 13:20:58 +03:00
Wu Di 60b0c298a9 Use optional unwrapping 2015-06-16 15:15:00 +08:00
Wu Di 2c521aeff0 Fix optional unwrap error when calling removeFromSuperview 2015-06-16 11:56:34 +08:00
6 changed files with 225 additions and 87 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'KDCircularProgress'
s.version = '1.0'
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
+148 -61
View File
@@ -12,6 +12,7 @@ public enum KDCircularProgressGlowMode {
case Forward, Reverse, Constant, NoGlow
}
@IBDesignable
public class KDCircularProgress: UIView {
private struct ConversionFunctions {
@@ -61,7 +62,7 @@ public class KDCircularProgress: UIView {
}
}
public var angle: Int! {
@IBInspectable public var angle: Int = 0 {
didSet {
if self.isAnimating() {
self.pauseAnimation()
@@ -70,66 +71,76 @@ public class KDCircularProgress: UIView {
}
}
public var startAngle: Int! {
@IBInspectable public var startAngle: Int = 0 {
didSet {
progressLayer.startAngle = UtilityFunctions.Mod(startAngle, range: 360, minMax: (0,360))
progressLayer.setNeedsDisplay()
}
}
public var clockwise: Bool! {
@IBInspectable public var clockwise: Bool = true {
didSet {
progressLayer.clockwise = clockwise
progressLayer.setNeedsDisplay()
}
}
public var roundedCorners: Bool! {
@IBInspectable public var roundedCorners: Bool = true {
didSet {
progressLayer.roundedCorners = roundedCorners
}
}
public var gradientRotateSpeed: CGFloat! {
@IBInspectable public var gradientRotateSpeed: CGFloat = 0 {
didSet {
progressLayer.gradientRotateSpeed = gradientRotateSpeed
}
}
public var glowAmount: CGFloat! {//Between 0 and 1
@IBInspectable public var glowAmount: CGFloat = 1.0 {//Between 0 and 1
didSet {
progressLayer.glowAmount = UtilityFunctions.Clamp(glowAmount, minMax: (0, 1))
}
}
public var glowMode: KDCircularProgressGlowMode! {
@IBInspectable public var glowMode: KDCircularProgressGlowMode = .Forward {
didSet {
progressLayer.glowMode = glowMode
}
}
public var progressThickness: CGFloat! {//Between 0 and 1
@IBInspectable public var progressThickness: CGFloat = 0.4 {//Between 0 and 1
didSet {
progressThickness = UtilityFunctions.Clamp(progressThickness, minMax: (0, 1))
progressLayer.progressThickness = progressThickness/2
}
}
public var trackThickness: CGFloat! {//Between 0 and 1
@IBInspectable public var trackThickness: CGFloat = 0.5 {//Between 0 and 1
didSet {
trackThickness = UtilityFunctions.Clamp(trackThickness, minMax: (0, 1))
progressLayer.trackThickness = trackThickness/2
}
}
public var trackColor: UIColor! {
@IBInspectable public var trackColor: UIColor = UIColor.blackColor() {
didSet {
progressLayer.trackColor = trackColor
progressLayer.setNeedsDisplay()
}
}
public var progressColors: [UIColor]! {
@IBInspectable public var progressInsideFillColor: UIColor? = nil {
didSet {
if let color = progressInsideFillColor {
progressLayer.progressInsideFillColor = color
} else {
progressLayer.progressInsideFillColor = UIColor.clearColor()
}
}
}
@IBInspectable public var progressColors: [UIColor]! {
get {
return progressLayer.colorsArray
}
@@ -139,13 +150,21 @@ public class KDCircularProgress: UIView {
}
}
//These are used only from the Interface-Builder. Changing these from code will have no effect.
//Also IB colors are limited to 3, whereas programatically we can have an arbitrary number of them.
@objc @IBInspectable private var IBColor1: UIColor?
@objc @IBInspectable private var IBColor2: UIColor?
@objc @IBInspectable private var IBColor3: UIColor?
private var animationCompletionBlock: ((Bool) -> Void)?
override public init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clearColor()
userInteractionEnabled = false
setInitialValues()
refreshValues()
checkAndSetIBColors()
}
convenience public init(frame:CGRect, colors: UIColor...) {
@@ -154,13 +173,52 @@ public class KDCircularProgress: UIView {
}
required public init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
super.init(coder: aDecoder)!
translatesAutoresizingMaskIntoConstraints = false
userInteractionEnabled = false
setInitialValues()
refreshValues()
}
public override func awakeFromNib() {
checkAndSetIBColors()
}
override public class func layerClass() -> AnyClass {
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()
setColors(UIColor.whiteColor(), UIColor.redColor())
}
private func refreshValues() {
progressLayer.angle = angle
progressLayer.startAngle = UtilityFunctions.Mod(startAngle, range: 360, minMax: (0,360))
progressLayer.clockwise = clockwise
progressLayer.roundedCorners = roundedCorners
progressLayer.gradientRotateSpeed = gradientRotateSpeed
progressLayer.glowAmount = UtilityFunctions.Clamp(glowAmount, minMax: (0, 1))
progressLayer.glowMode = glowMode
progressLayer.progressThickness = progressThickness/2
progressLayer.trackColor = trackColor
progressLayer.trackThickness = trackThickness/2
}
private func checkAndSetIBColors() {
let nonNilColors = [IBColor1, IBColor2, IBColor3].filter { $0 != nil}.map { $0! }
if nonNilColors.count > 0 {
setColors(nonNilColors)
}
}
public func setColors(colors: UIColor...) {
setColors(colors)
}
@@ -170,30 +228,24 @@ public class KDCircularProgress: UIView {
progressLayer.setNeedsDisplay()
}
private func setInitialValues() { // We have this because didSet effects are not triggered when invoked directly from init method
radius = (frame.size.width/2.0) * 0.8 //We always apply a 20% padding, stopping glows from being clipped
angle = 0
startAngle = 0
clockwise = true
roundedCorners = false
gradientRotateSpeed = 0
glowAmount = 1
glowMode = .Forward
progressThickness = 0.4
trackThickness = 0.5
trackColor = UIColor.blackColor()
setColors(UIColor.whiteColor(), UIColor.redColor())
}
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
@@ -201,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() {
@@ -216,11 +268,16 @@ public class KDCircularProgress: UIView {
angle = currentValue
}
public func stopAnimation() {
progressLayer.removeAllAnimations()
angle = 0
}
public func isAnimating() -> Bool {
return progressLayer.animationForKey("angle") != nil
}
override public func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
override public func animationDidStop(anim: CAAnimation, finished flag: Bool) {
if let completionBlock = animationCompletionBlock {
completionBlock(flag)
animationCompletionBlock = nil
@@ -228,7 +285,9 @@ public class KDCircularProgress: UIView {
}
public override func didMoveToWindow() {
progressLayer.contentsScale = window!.screen.scale
if let window = window {
progressLayer.contentsScale = window.screen.scale
}
}
public override func willMoveToSuperview(newSuperview: UIView?) {
@@ -237,29 +296,50 @@ public class KDCircularProgress: UIView {
}
}
public override func prepareForInterfaceBuilder() {
setInitialValues()
refreshValues()
checkAndSetIBColors()
progressLayer.setNeedsDisplay()
}
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!
var trackThickness: CGFloat!
var trackColor: UIColor!
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:
@@ -274,11 +354,11 @@ public class KDCircularProgress: UIView {
}
}
override class func needsDisplayForKey(key: String!) -> Bool {
override class func needsDisplayForKey(key: String) -> Bool {
return key == "angle" ? true : super.needsDisplayForKey(key)
}
override init!(layer: AnyObject!) {
override init(layer: AnyObject) {
super.init(layer: layer)
let progressLayer = layer as! KDCircularProgressViewLayer
radius = progressLayer.radius
@@ -295,15 +375,15 @@ public class KDCircularProgress: UIView {
colorsArray = progressLayer.colorsArray
}
override init!() {
override init() {
super.init()
}
required init(coder aDecoder: NSCoder) {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawInContext(ctx: CGContext!) {
override func drawInContext(ctx: CGContext) {
UIGraphicsPushContext(ctx)
let rect = bounds
let size = rect.size
@@ -313,9 +393,11 @@ public class KDCircularProgress: UIView {
let arcRadius = max(radius - trackLineWidth/2, radius - progressLineWidth/2)
CGContextAddArc(ctx, CGFloat(size.width/2.0), CGFloat(size.height/2.0), arcRadius, 0, CGFloat(M_PI * 2), 0)
trackColor.set()
CGContextSetStrokeColorWithColor(ctx, trackColor.CGColor)
CGContextSetFillColorWithColor(ctx, progressInsideFillColor.CGColor)
CGContextSetLineWidth(ctx, trackLineWidth)
CGContextSetLineCap(ctx, kCGLineCapButt)
CGContextDrawPath(ctx, kCGPathStroke)
CGContextSetLineCap(ctx, CGLineCap.Butt)
CGContextDrawPath(ctx, .FillStroke)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
let imageCtx = UIGraphicsGetCurrentContext()
@@ -327,11 +409,11 @@ public class KDCircularProgress: UIView {
if glowValue > 0 {
CGContextSetShadowWithColor(imageCtx, CGSizeZero, glowValue, UIColor.blackColor().CGColor)
}
CGContextSetLineCap(imageCtx, roundedCorners == true ? kCGLineCapRound : kCGLineCapButt)
CGContextSetLineCap(imageCtx, roundedCorners == true ? .Round : .Butt)
CGContextSetLineWidth(imageCtx, progressLineWidth)
CGContextDrawPath(imageCtx, kCGPathStroke)
CGContextDrawPath(imageCtx, .Stroke)
let drawMask: CGImageRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext())
let drawMask: CGImageRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext())!
UIGraphicsEndImageContext()
CGContextSaveGState(ctx)
@@ -351,7 +433,7 @@ public class KDCircularProgress: UIView {
for color in rgbColorsArray {
let colorComponents: UnsafePointer<CGFloat> = CGColorGetComponents(color.CGColor)
componentsArray.extend([colorComponents[0],colorComponents[1],colorComponents[2],1.0])
componentsArray.appendContentsOf([colorComponents[0],colorComponents[1],colorComponents[2],1.0])
}
drawGradientWithContext(ctx, componentsArray: componentsArray)
@@ -366,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
@@ -379,7 +461,7 @@ 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
}
@@ -388,15 +470,15 @@ public class KDCircularProgress: UIView {
let floatPi = CGFloat(M_PI)
let rotateSpeed = clockwise == true ? gradientRotateSpeed : gradientRotateSpeed * -1
let angleInRadians = ConversionFunctions.DegreesToRadians(rotateSpeed * CGFloat(angle) - 90)
var oppositeAngle = angleInRadians > floatPi ? angleInRadians - floatPi : angleInRadians + floatPi
let oppositeAngle = angleInRadians > floatPi ? angleInRadians - floatPi : angleInRadians + floatPi
let startPoint = CGPoint(x: (cos(angleInRadians) * halfX) + halfX, y: (sin(angleInRadians) * halfX) + halfX)
let endPoint = CGPoint(x: (cos(oppositeAngle) * halfX) + halfX, y: (sin(oppositeAngle) * halfX) + halfX)
CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0)
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 {
@@ -414,5 +496,10 @@ public class KDCircularProgress: UIView {
return result
}
}
private func invalidateGradientCache() {
gradientCache = nil
locationsCache = nil
}
}
}
@@ -168,6 +168,7 @@
BC9E757E1A8CE4A500B1DF3D /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Kaan Dedeoglu";
TargetAttributes = {
@@ -418,6 +419,7 @@
BC9E75A71A8CE4A500B1DF3D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
BC9E75A81A8CE4A500B1DF3D /* Build configuration list for PBXNativeTarget "KDCircularProgressExampleTests" */ = {
isa = XCConfigurationList;
@@ -426,6 +428,7 @@
BC9E75AA1A8CE4A500B1DF3D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" 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>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
</dependencies>
<scenes>
<!--View Controller-->
@@ -18,6 +20,7 @@
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="360" translatesAutoresizingMaskIntoConstraints="NO" id="BHN-x6-Zsx">
<rect key="frame" x="61" y="478" width="198" height="31"/>
<animations/>
<constraints>
<constraint firstAttribute="height" constant="30" id="6DH-hv-h4S"/>
<constraint firstAttribute="width" constant="194" id="oTI-kD-sOa"/>
@@ -28,6 +31,7 @@
</slider>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5M2-Yi-RuL">
<rect key="frame" x="112" y="523" width="96" height="30"/>
<animations/>
<constraints>
<constraint firstAttribute="width" constant="96" id="T9z-qf-POZ"/>
<constraint firstAttribute="height" constant="30" id="h5a-bV-EMl"/>
@@ -39,24 +43,62 @@
<action selector="animateButtonTapped:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="b0F-cY-phl"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wev-Tz-pfW" customClass="KDCircularProgress" customModule="KDCircularProgressExample" customModuleProvider="target">
<rect key="frame" x="60" y="20" width="200" height="200"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="width" constant="200" id="191-H5-EIc"/>
<constraint firstAttribute="width" secondItem="wev-Tz-pfW" secondAttribute="height" multiplier="1:1" id="Fsf-y4-1ta"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="angle">
<integer key="value" value="320"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="IBColor1">
<color key="value" red="0.97441762909999996" green="1" blue="0.31255436479999998" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="IBColor2">
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="IBColor3">
<color key="value" red="0.085719833812801863" green="0.98039215690000003" blue="0.39604470297983985" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="startAngle">
<integer key="value" value="-90"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="clockwise" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="glowAmount">
<real key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="progressThickness">
<real key="value" value="0.20000000000000001"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="trackThickness">
<real key="value" value="1"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="gradientRotateSpeed">
<real key="value" value="2"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<animations/>
<color key="backgroundColor" red="0.4736600907821229" green="0.4736600907821229" blue="0.4736600907821229" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="BHN-x6-Zsx" secondAttribute="centerX" id="Arq-5P-YRp"/>
<constraint firstItem="wev-Tz-pfW" firstAttribute="top" secondItem="ghF-CJ-0yv" secondAttribute="bottom" id="EcI-a0-AkN"/>
<constraint firstItem="5M2-Yi-RuL" firstAttribute="top" secondItem="BHN-x6-Zsx" secondAttribute="bottom" constant="15" id="GMQ-0i-VMb"/>
<constraint firstAttribute="centerX" secondItem="5M2-Yi-RuL" secondAttribute="centerX" id="IEH-Lm-rgx"/>
<constraint firstAttribute="centerX" secondItem="wev-Tz-pfW" secondAttribute="centerX" id="jKJ-82-cfb"/>
<constraint firstItem="o67-py-2aK" firstAttribute="top" secondItem="5M2-Yi-RuL" secondAttribute="bottom" constant="15" id="zhX-dr-Rnn"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="218" y="319"/>
<point key="canvasLocation" x="410" y="396"/>
</scene>
</scenes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>
@@ -18,16 +18,15 @@ class ViewController: UIViewController {
progress = KDCircularProgress(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
progress.startAngle = -90
progress.progressThickness = 0.05
progress.trackThickness = 0.4
progress.progressThickness = 0.2
progress.trackThickness = 0.6
progress.clockwise = true
progress.center = view.center
progress.gradientRotateSpeed = 2
progress.roundedCorners = false
progress.glowMode = .Forward
progress.glowAmount = 0.0
// progress.setColors(UIColor.cyanColor() ,UIColor.whiteColor(), UIColor.magentaColor())
progress.setColors(UIColor.whiteColor())
progress.glowAmount = 0.9
progress.setColors(UIColor.cyanColor() ,UIColor.whiteColor(), UIColor.magentaColor(), UIColor.whiteColor(), UIColor.orangeColor())
progress.center = CGPoint(x: view.center.x, y: view.center.y + 25)
view.addSubview(progress)
}
@@ -36,11 +35,11 @@ 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 {
println("animation stopped, completed")
print("animation stopped, completed")
} else {
println("animation stopped, was interrupted")
print("animation stopped, was interrupted")
}
}
}
+13 -6
View File
@@ -1,5 +1,9 @@
# KDCircularProgress
`KDCircularProgress` is a circular progress view written in Swift. It makes it possible to have gradients in the progress view, along with glows and animations. Here's an example
`KDCircularProgress` is a circular progress view written in Swift. It makes it possible to have gradients in the progress view, along with glows and animations.
KDCircularProgress also has `IBInspectable` and `IBDesignable` support, so you can configure and preview inside the `Interface Builder`.
Here's an example
[Youtube Link](http://youtu.be/iIdas72MXOg)
@@ -34,6 +38,9 @@ view.addSubview(progress)
## Properties
####progressColors: `[UIColor]`
The colors used to generate the gradient of the progress. You can also set this using the variadic `setColors(UIColor...)` method. A gradient is used only if there is more than one color. A fill is used otherwise. The default is a white fill.
####angle: `Int`
The angle of the progress. Between 0 and 360 (inclusive). Simply change its value in order to change the visual progress of the component. Default is 0.
@@ -47,7 +54,7 @@ Clockwise if true, Counter-clockwise if false. Default is true.
When true, the ends of the progress track will be drawn with a half circle radius. Default is false.
####gradientRotateSpeed: `CGFloat`
Describes how many times the underlying gradient will turn for each full cycle of the progress. Integer values recommended. Default is 0.
Describes how many times the underlying gradient will perform a 2π rotation for each full cycle of the progress. Integer values recommended. Default is 0.
####glowAmount: `CGFloat`
The intensity of the glow. Between 0 and 1.0. Default is 1.0.
@@ -70,10 +77,10 @@ The thickness of the progress. Between 0 and 1. Default is 0.4
The thickness of the background track. Between 0 and 1. Default is 0.5
####trackColor: `UIColor`
The color of the background track. Default is black.
The color of the background track. Default is `UIColor.blackColor()`.
####progressColors: `[UIColor]`
The colors used to generate the gradient of the progress. You can also set this using the variadic setColors(UIColor...) method. A gradient is used only if there is more than one color. A fill is used otherwise. The default is a white fill.
####progressInsideFillColor: `UIColor`
The color of the center of the circle. Default is `UIColor.clearColor()`.
##Methods
```swift
@@ -123,7 +130,7 @@ Prefering light colors in the gradients gives better results. As mentioned befor
- [x] Add example project
- [ ] Carthage Support
- [x] Cocoapods Support
- [ ] IBDesignable/IBInspectable support
- [x] IBDesignable/IBInspectable support
- [ ] Adding a `progress` property as an alternative to `angle`
- [ ] Clean up