diff --git a/ARSLineProgress.xcodeproj/project.pbxproj b/ARSLineProgress.xcodeproj/project.pbxproj index 2dde1e3..7cce35b 100644 --- a/ARSLineProgress.xcodeproj/project.pbxproj +++ b/ARSLineProgress.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 27454BD31C4C18E300DBB38C /* GreatStuff.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27454BD21C4C18E300DBB38C /* GreatStuff.framework */; }; 27454BD41C4C18E300DBB38C /* GreatStuff.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 27454BD21C4C18E300DBB38C /* GreatStuff.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 27454BD61C4C239900DBB38C /* ViewController2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27454BD51C4C239900DBB38C /* ViewController2.swift */; }; 276406BB1C3832B600BCE105 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 276406BA1C3832B600BCE105 /* AppDelegate.swift */; }; 276406BD1C3832B600BCE105 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 276406BC1C3832B600BCE105 /* ViewController.swift */; }; 276406C01C3832B700BCE105 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 276406BE1C3832B700BCE105 /* Main.storyboard */; }; @@ -32,6 +33,7 @@ /* Begin PBXFileReference section */ 27454BD21C4C18E300DBB38C /* GreatStuff.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = GreatStuff.framework; sourceTree = ""; }; + 27454BD51C4C239900DBB38C /* ViewController2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController2.swift; sourceTree = ""; }; 276406B71C3832B600BCE105 /* ARSLineProgress.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ARSLineProgress.app; sourceTree = BUILT_PRODUCTS_DIR; }; 276406BA1C3832B600BCE105 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 276406BC1C3832B600BCE105 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -75,6 +77,7 @@ children = ( 276406BA1C3832B600BCE105 /* AppDelegate.swift */, 276406BC1C3832B600BCE105 /* ViewController.swift */, + 27454BD51C4C239900DBB38C /* ViewController2.swift */, 276406BE1C3832B700BCE105 /* Main.storyboard */, 276406C11C3832B700BCE105 /* Assets.xcassets */, 276406C31C3832B700BCE105 /* LaunchScreen.storyboard */, @@ -157,6 +160,7 @@ files = ( 276406BD1C3832B600BCE105 /* ViewController.swift in Sources */, 276406BB1C3832B600BCE105 /* AppDelegate.swift in Sources */, + 27454BD61C4C239900DBB38C /* ViewController2.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ARSLineProgress/Base.lproj/Main.storyboard b/ARSLineProgress/Base.lproj/Main.storyboard index 25a2617..65e02e3 100644 --- a/ARSLineProgress/Base.lproj/Main.storyboard +++ b/ARSLineProgress/Base.lproj/Main.storyboard @@ -5,10 +5,10 @@ - + - + diff --git a/ARSLineProgress/ViewController2.swift b/ARSLineProgress/ViewController2.swift new file mode 100644 index 0000000..724f8ec --- /dev/null +++ b/ARSLineProgress/ViewController2.swift @@ -0,0 +1,185 @@ +// +// ViewController2.swift +// ARSLineProgress +// +// Created by Yaroslav Arsenkin on 17.01.16. +// Copyright © 2016 Iaroslav Arsenkin. All rights reserved. +// + +import UIKit +import GreatStuff + +class ViewController2: UIViewController { + + private var backgroundRect = UIView() + private var outerCircle = CAShapeLayer() + private var middleCircle = CAShapeLayer() + private var innerCircle = CAShapeLayer() + private var multiplier: CGFloat = 1.0 + private var progress: CGFloat = 0.0 + + override func viewDidLoad() { + super.viewDidLoad() + + createBackgroundRect() + createCircles() + animateCircles() + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 10 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(4.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 10 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(5.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(6.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(7.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 10 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 10 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(4.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 10 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(5.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(6.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 3 + }) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(7.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), { () -> Void in + self.progress += 10 + }) + + + NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("incrementMultiplier"), userInfo: nil, repeats: true) + } + + func incrementMultiplier() { + if multiplier > 100 { return } + if progress / multiplier > 10 { + if multiplier < progress { + multiplier++ + } + } else { + if multiplier < progress { + multiplier += 0.5 + } + } + + let oPath = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(backgroundRect.bounds), CGRectGetMidY(backgroundRect.bounds)), radius: 40.0, startAngle: 0, endAngle: CGFloat(M_PI) / 180 * 3.6 * multiplier, clockwise: true) + outerCircle.path = oPath.CGPath + + let mPath = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(backgroundRect.bounds), CGRectGetMidY(backgroundRect.bounds)), radius: 30.0, startAngle: 0, endAngle: CGFloat(M_PI) / 180 * 3.6 * multiplier, clockwise: true) + middleCircle.path = mPath.CGPath + + let iPath = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(backgroundRect.bounds), CGRectGetMidY(backgroundRect.bounds)), radius: 20.0, startAngle: 0, endAngle: CGFloat(M_PI) / 180 * 3.6 * multiplier, clockwise: true) + innerCircle.path = iPath.CGPath + } + +} + +// MARK: - Circle Creation + +private extension ViewController2 { + + func createBackgroundRect() { + let screenCenter = CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds)) + backgroundRect.frame = CGRectMake(screenCenter.x - 100, screenCenter.y - 50, 200, 100) + backgroundRect.backgroundColor = UIColor.whiteColor() + backgroundRect.layer.cornerRadius = 20 + view.addSubview(backgroundRect) + } + + func createCircles() { + createOuterCircle() + createMiddleCircle() + createInnerCircle() + } + + func createOuterCircle() { + let path = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(backgroundRect.bounds), CGRectGetMidY(backgroundRect.bounds)), radius: 40.0, startAngle: 0, endAngle: CGFloat(M_PI) / 180 * 3.6 * multiplier, clockwise: true) + outerCircle.path = path.CGPath + outerCircle.frame = backgroundRect.bounds + outerCircle.lineWidth = 2.0 + outerCircle.strokeColor = UIColor.gs_colorWithRGB(130.0, green: 149.0, blue: 173.0, alpha: 1.0).CGColor + outerCircle.fillColor = UIColor.clearColor().CGColor + backgroundRect.layer.addSublayer(outerCircle) + } + + func createMiddleCircle() { + let path = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(backgroundRect.bounds), CGRectGetMidY(backgroundRect.bounds)), radius: 30.0, startAngle: 0, endAngle: CGFloat(M_PI) / 180 * 3.6 * multiplier, clockwise: true) + middleCircle.path = path.CGPath + middleCircle.frame = backgroundRect.bounds + middleCircle.lineWidth = 2.0 + middleCircle.strokeColor = UIColor.gs_colorWithRGB(82.0, green: 124.0, blue: 194.0, alpha: 1.0).CGColor + middleCircle.fillColor = UIColor.clearColor().CGColor + backgroundRect.layer.addSublayer(middleCircle) + } + + func createInnerCircle() { + let path = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(backgroundRect.bounds), CGRectGetMidY(backgroundRect.bounds)), radius: 20.0, startAngle: 0, endAngle: CGFloat(M_PI) / 180 * 3.6 * multiplier, clockwise: true) + innerCircle.path = path.CGPath + innerCircle.frame = backgroundRect.bounds + innerCircle.lineWidth = 2.0 + innerCircle.strokeColor = UIColor.gs_colorWithRGB(60.0, green: 132.0, blue: 196.0, alpha: 1.0).CGColor + innerCircle.fillColor = UIColor.clearColor().CGColor + backgroundRect.layer.addSublayer(innerCircle) + } + +} + +// MARK: - Animation + +private extension ViewController2 { + + func animateCircles() { + let outerAnimation = CABasicAnimation(keyPath: "transform.rotation") + outerAnimation.fromValue = 0.0 + outerAnimation.toValue = 2 * CGFloat(M_PI) + outerAnimation.duration = 4.0 + outerAnimation.repeatCount = 100 + outerAnimation.additive = true + outerCircle.addAnimation(outerAnimation, forKey: "outerCircleRotation") + + let middleAnimation = CABasicAnimation(keyPath: "transform.rotation") + middleAnimation.fromValue = 0.0 + middleAnimation.toValue = 2 * CGFloat(M_PI) + middleAnimation.duration = 2.0 + middleAnimation.repeatCount = 100 + middleAnimation.additive = true + middleCircle.addAnimation(middleAnimation, forKey: "middleCircleRotation") + + let innerAnimation = CABasicAnimation(keyPath: "transform.rotation") + innerAnimation.fromValue = 0.0 + innerAnimation.toValue = 2 * CGFloat(M_PI) + innerAnimation.duration = 1.0 + innerAnimation.repeatCount = 100 + innerAnimation.additive = true + innerCircle.addAnimation(innerAnimation, forKey: "middleCircleRotation") + } + +} \ No newline at end of file