From 50518c8c97cf2d7c67be8ef140f4c04b070080f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=EF=A3=BF?= <1933549736@qq.com> Date: Thu, 23 Nov 2017 12:02:23 +0800 Subject: [PATCH 1/2] create develop branch and to develop new version --- .DS_Store | Bin 0 -> 6148 bytes AnimatedPaths.xcodeproj/project.pbxproj | 22 +- .../contents.xcworkspacedata | 7 + AnimatedPaths/RCAnimatedPath.swift | 355 ++++++++++++++++++ AnimatedPaths/ViewController.swift | 27 +- 5 files changed, 397 insertions(+), 14 deletions(-) create mode 100644 .DS_Store create mode 100644 AnimatedPaths.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 AnimatedPaths/RCAnimatedPath.swift diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..af7a2b9a4e0202a93901a3666069e61c5191548c GIT binary patch literal 6148 zcmeHK%}N774E|z!D2ULT9_Il>>>I45-i3VuOIuo{-Cf!$9``|fSiel-PjNknAR-A& zzU)kroqVt}8vrtXn2&%VfB}c1sL>%h-MMt+&OM^!98>JEz#KQ2b|m_XQ@ZyPT%p1p zHr)05{`Xj6_gHSLbzLp3LY#i>i3>bohMLtc&|pjJe!U!(vwG85;pfl9Z)Rv#A2VE9 zqR_!WFc1s`1Hr&g7~q|)GB`F29Sj5m!N3~>dOjo$#lo>Q%tr@RZUKmWPG_O5y@bXj z$HK8SivJsPo}fU&n}^YfneajG9dj)IT^D$zgs`msdsJSxaCk$zg7(j?Sr2HKIl1emKSY3 asZGDau{G2zI-kRd@gtB42^9?d0s}9{nJ%ON literal 0 HcmV?d00001 diff --git a/AnimatedPaths.xcodeproj/project.pbxproj b/AnimatedPaths.xcodeproj/project.pbxproj index f6a5bcf..bb6c994 100644 --- a/AnimatedPaths.xcodeproj/project.pbxproj +++ b/AnimatedPaths.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 009F0CBC1FC67E060096B0E3 /* RCAnimatedPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009F0CBB1FC67E060096B0E3 /* RCAnimatedPath.swift */; }; 00B299751C7C413400521D96 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B299741C7C413400521D96 /* AppDelegate.swift */; }; 00B299771C7C413400521D96 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B299761C7C413400521D96 /* ViewController.swift */; }; 00B2997A1C7C413400521D96 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 00B299781C7C413400521D96 /* Main.storyboard */; }; @@ -15,6 +16,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 009F0CBB1FC67E060096B0E3 /* RCAnimatedPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RCAnimatedPath.swift; sourceTree = ""; }; 00B299711C7C413400521D96 /* AnimatedPaths.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnimatedPaths.app; sourceTree = BUILT_PRODUCTS_DIR; }; 00B299741C7C413400521D96 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 00B299761C7C413400521D96 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -55,6 +57,7 @@ isa = PBXGroup; children = ( 00B299741C7C413400521D96 /* AppDelegate.swift */, + 009F0CBB1FC67E060096B0E3 /* RCAnimatedPath.swift */, 00B299761C7C413400521D96 /* ViewController.swift */, 00B299781C7C413400521D96 /* Main.storyboard */, 00B2997B1C7C413400521D96 /* Assets.xcassets */, @@ -98,7 +101,7 @@ CreatedOnToolsVersion = 7.2.1; DevelopmentTeam = W7YDEDGW4E; LastSwiftMigration = 0820; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; }; }; }; @@ -140,6 +143,7 @@ files = ( 00B299771C7C413400521D96 /* ViewController.swift in Sources */, 00B299751C7C413400521D96 /* AppDelegate.swift in Sources */, + 009F0CBC1FC67E060096B0E3 /* RCAnimatedPath.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -252,14 +256,16 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = W7YDEDGW4E; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = AnimatedPaths/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.Robin.AnimatedPaths; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "3a51cda8-3387-4c26-a945-c8fb51508664"; - PROVISIONING_PROFILE_SPECIFIER = "Development: Wildcard"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; @@ -269,14 +275,16 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = W7YDEDGW4E; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = AnimatedPaths/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.Robin.AnimatedPaths; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "3a51cda8-3387-4c26-a945-c8fb51508664"; - PROVISIONING_PROFILE_SPECIFIER = "Development: Wildcard"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; diff --git a/AnimatedPaths.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/AnimatedPaths.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/AnimatedPaths.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/AnimatedPaths/RCAnimatedPath.swift b/AnimatedPaths/RCAnimatedPath.swift new file mode 100644 index 0000000..dbf7806 --- /dev/null +++ b/AnimatedPaths/RCAnimatedPath.swift @@ -0,0 +1,355 @@ +// +// RCAnimatedPath.swift +// AnimatedPaths +// +// Created by Robin on 17/11/23. +// Copyright © 2017年 Robin. All rights reserved. +// + +import UIKit +import QuartzCore +import CoreText +import CoreGraphics + + + +class RCAnimatedPath +{ + //////////////////////// + // CREATE A SINGLETON // + + class var shared: RCAnimatedPath + { + struct Singleton + { + static let instance = RCAnimatedPath() + } + return Singleton.instance + } + + // CREATE A SINGLETON // + //////////////////////// + + + + var animationLayer: CALayer? + var pathLayer: CAShapeLayer? + + private var inputPath: CGPath! + private var inputDuration: CFTimeInterval = 10 + private var inputLineWidth: CGFloat = 10 + private var inputLineColor = UIColor.black + + private var inputRotationAngle: CGFloat = 0 + private var inputPolygonSidesNumber: Int = 6 + private var inputCornerRadius: Float = 8 + + private var inputText = "" + private var inputFontSize: CGFloat = 20 + private var inputFontName = "PingFangSC-Bold" + + + + func drawAnimatedCustomPath(in view: UIView, path: CGPath, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor) + { + self.inputDuration = duration + self.inputLineWidth = lineWidth + self.inputLineColor = lineColor + self.inputPath = path + + animationLayer = CALayer() + + animationLayer?.frame = CGRect(x: 0, y: 0, width: view.layer.bounds.width, height: view.layer.bounds.height) + view.layer.addSublayer(animationLayer!) + view.clipsToBounds = true + + setupDrawingLayer() + startAnimation() + } + + func drawAnimatedRectanglePath(in view: UIView, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor) + { + self.inputDuration = duration + self.inputLineWidth = lineWidth + self.inputLineColor = lineColor + + self.inputPath = rectanglePath(view: view) + + animationLayer = CALayer() + + animationLayer?.frame = CGRect(x: 0, y: 0, width: view.layer.bounds.width, height: view.layer.bounds.height) + view.layer.addSublayer(animationLayer!) + view.clipsToBounds = true + + setupDrawingLayer() + startAnimation() + } + + func drawAnimatedPolygonPath(in view: UIView, numberOfSides polygonSidesNumber: Int?, rotationAngle: CGFloat?, polygonCornerRadius: Float?, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor) + { + self.inputDuration = duration + self.inputLineWidth = lineWidth + self.inputLineColor = lineColor + if let _rotationAngle = rotationAngle + { + self.inputRotationAngle = _rotationAngle + } + if let _polygonSidesNumber = polygonSidesNumber + { + self.inputPolygonSidesNumber = _polygonSidesNumber + } + if let _polygonCornerRadius = polygonCornerRadius + { + self.inputCornerRadius = _polygonCornerRadius + } + + self.inputPath = polygonPath(view: view) + + + animationLayer = CALayer() + animationLayer?.frame = CGRect(x: 0, y: 0, width: view.layer.bounds.width, height: view.layer.bounds.height) + view.layer.addSublayer(animationLayer!) + + setupDrawingLayer() + startAnimation() + } + + func drawAnimatedText(in view: UIView, with text: String, duration: CFTimeInterval, lineWidth: CGFloat, textColor: UIColor, fontName: String?, fontSize: CGFloat?) + { + self.inputText = text + self.inputDuration = duration + self.inputLineWidth = lineWidth + self.inputLineColor = textColor + if let _fontSize = fontSize + { + self.inputFontSize = _fontSize + } + if let _fontName = fontName + { + self.inputFontName = _fontName + } + + animationLayer = CALayer() + animationLayer?.frame = CGRect(x: 0, y: 0, width: view.layer.bounds.width, height: view.layer.bounds.height) + view.layer.addSublayer(animationLayer!) + + setupTextLayer(in: view) + startAnimation() + } + + + func setupDrawingLayer() + { + clearLayer() + + if let _ = animationLayer + { + let pathRect: CGRect = animationLayer!.bounds + + + let pathShapeLayer = CAShapeLayer() + pathShapeLayer.frame = animationLayer!.bounds + pathShapeLayer.bounds = pathRect + pathShapeLayer.isGeometryFlipped = true + pathShapeLayer.path = inputPath + pathShapeLayer.strokeColor = inputLineColor.cgColor + pathShapeLayer.fillColor = nil + pathShapeLayer.lineWidth = inputLineWidth + pathShapeLayer.lineJoin = kCALineJoinBevel + + animationLayer!.addSublayer(pathShapeLayer) + + pathLayer = pathShapeLayer + } + } + + func setupTextLayer(in view: UIView) + { + clearLayer() + + if let _ = animationLayer + { + let font = CTFontCreateWithName(inputFontName as CFString?, inputFontSize, nil) + let attrStr = NSAttributedString(string: inputText, attributes: [kCTFontAttributeName as String: font]) + let line = CTLineCreateWithAttributedString(attrStr) + let runArray = CTLineGetGlyphRuns(line) + + let letters = CGMutablePath() + + for runIndex in 0.. CGPath + { + //start point - left-down corner + var point = CGPoint(x: inputLineWidth/2, y: 0) + let path = UIBezierPath() + path.move(to: point) + //left-up corner + point = CGPoint(x: inputLineWidth/2, y: view.frame.height) + path.addLine(to: point) + path.move(to: CGPoint(x: inputLineWidth/2, y: view.frame.height - inputLineWidth/2)) + //right-up corner + point = CGPoint(x: view.frame.width, y: view.frame.height - inputLineWidth/2) + path.addLine(to: point) + path.move(to: CGPoint(x: view.frame.width - inputLineWidth/2, y: view.frame.height - inputLineWidth/2)) + //right-down corner + point = CGPoint(x: view.frame.width - inputLineWidth/2, y: 0) + path.addLine(to: point) + path.move(to: CGPoint(x: view.frame.width - inputLineWidth/2, y: inputLineWidth/2)) + //start point - left-down corner + point = CGPoint(x: 0, y: inputLineWidth/2) + path.addLine(to: point) + + path.close() + + return path.cgPath + } + + private func polygonPath(view: UIView) -> CGPath + { + let path = UIBezierPath() + + let theta = Float(2.0 * .pi) / Float(inputPolygonSidesNumber) + let offset = inputCornerRadius * tanf(theta / 2.0) + let squareWidth = Float(min(view.frame.size.width, view.frame.size.height)) + + var length = squareWidth - Float(inputLineWidth) + + if inputPolygonSidesNumber % 4 != 0 + { + length = length * cosf(theta / 2.0) + offset / 2.0 + } + + let sideLength = length * tanf(theta / 2.0) + + var point = CGPoint(x: CGFloat((squareWidth / 2.0) + (sideLength / 2.0) - offset), y: CGFloat(squareWidth - (squareWidth - length) / 2.0)) + var angle = Float(Double.pi) + path.move(to: point) + + for _ in 0 ..< inputPolygonSidesNumber + { + + let x = Float(point.x) + (sideLength - offset * 2.0) * cosf(angle) + let y = Float(point.y) + (sideLength - offset * 2.0) * sinf(angle) + + point = CGPoint(x: CGFloat(x), y: CGFloat(y)) + path.addLine(to: point) + + let centerX = Float(point.x) + inputCornerRadius * cosf(angle + Float(Double.pi/2)) + let centerY = Float(point.y) + inputCornerRadius * sinf(angle + Float(Double.pi/2)) + + let center = CGPoint(x: CGFloat(centerX), y: CGFloat(centerY)) + + let startAngle = CGFloat(angle) - CGFloat(Double.pi/2) + let endAngle = CGFloat(angle) + CGFloat(theta) - CGFloat(Double.pi/2) + + path.addArc(withCenter: center, radius: CGFloat(inputCornerRadius), startAngle: startAngle, endAngle: endAngle, clockwise: true) + + point = path.currentPoint + angle += theta + } + + path.close() + + + // ROTATE + //get the center and transform the path so it's centered at the origin + let bounds = path.cgPath.boundingBox + let center = CGPoint(x:bounds.midX, y:bounds.midY) + + let toOrigin = CGAffineTransform(translationX: -center.x, y: -center.y) + path.apply(toOrigin) + + //rotate around the origin + let rotAngle = inputRotationAngle * CGFloat(Double.pi) / 180 + let rotation = CGAffineTransform(rotationAngle: CGFloat(rotAngle)) + path.apply(rotation) + + //translate back to the origin + let fromOrigin = CGAffineTransform(translationX: center.x, y: center.y) + path.apply(fromOrigin) + + return path.cgPath + } + +}//end of class diff --git a/AnimatedPaths/ViewController.swift b/AnimatedPaths/ViewController.swift index 220261e..9f47f15 100644 --- a/AnimatedPaths/ViewController.swift +++ b/AnimatedPaths/ViewController.swift @@ -21,12 +21,25 @@ class ViewController: UIViewController, CAAnimationDelegate { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. - animationLayer = CALayer() - animationLayer?.frame = CGRect(x: 20.0, y: 40.0, width: self.view.layer.bounds.width - 40.0, height: self.view.layer.bounds.height - 84.0) - self.view.layer.addSublayer(animationLayer!) + let targetView: UIView = self.view - setupDrawingLayer() - startAnimation() + RCAnimatedPath().drawAnimatedRectanglePath(in: targetView, duration: 10, lineWidth: 20, lineColor: UIColor.red) + + RCAnimatedPath().drawAnimatedPolygonPath(in: targetView, numberOfSides: 8, rotationAngle: 30, polygonCornerRadius: 8, duration: 10, lineWidth: 5, lineColor: UIColor.gray) + + RCAnimatedPath().drawAnimatedText(in: targetView, with: "K E G", duration: 10, lineWidth: 2, textColor: UIColor.blue, fontName: "anyFontName", fontSize: 50) + +// RCAnimatedPath().drawAnimatedCustomPath(in: targetView, path: myPath, duration: 15, lineWidth: 5, lineColor: UIColor.blue) + + RCAnimatedPath.shared.drawAnimatedRectanglePath(in: targetView, duration: 10, lineWidth: 20, lineColor: UIColor.red) + + +// animationLayer = CALayer() +// animationLayer?.frame = CGRect(x: 20.0, y: 40.0, width: self.view.layer.bounds.width - 40.0, height: self.view.layer.bounds.height - 84.0) +// self.view.layer.addSublayer(animationLayer!) +// +// setupDrawingLayer() +// startAnimation() } func clearLayer() { @@ -96,8 +109,8 @@ class ViewController: UIViewController, CAAnimationDelegate { func setupTextLayer() { clearLayer() - let font = CTFontCreateWithName("STHeitiSC-Light" as CFString, 120, nil) - let attrStr = NSAttributedString(string: "你好Swift", attributes: [kCTFontAttributeName as String: font]) + let font = CTFontCreateWithName("PingFangSC-Light" as CFString, 120, nil) + let attrStr = NSAttributedString(string: "Hello Swift", attributes: [kCTFontAttributeName as String: font]) let line = CTLineCreateWithAttributedString(attrStr) let runArray = CTLineGetGlyphRuns(line) From e0982b12ffd887785ec6bc11945ced746a2c7bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=EF=A3=BF?= <1933549736@qq.com> Date: Thu, 23 Nov 2017 18:03:07 +0800 Subject: [PATCH 2/2] Refactoring code all code --- .../Base.lproj/LaunchScreen.storyboard | 16 +- AnimatedPaths/Base.lproj/Main.storyboard | 34 +-- AnimatedPaths/RCAnimatedPath.swift | 91 +++---- AnimatedPaths/ViewController.swift | 243 +++++------------- 4 files changed, 135 insertions(+), 249 deletions(-) diff --git a/AnimatedPaths/Base.lproj/LaunchScreen.storyboard b/AnimatedPaths/Base.lproj/LaunchScreen.storyboard index 2e721e1..22ff8e4 100644 --- a/AnimatedPaths/Base.lproj/LaunchScreen.storyboard +++ b/AnimatedPaths/Base.lproj/LaunchScreen.storyboard @@ -1,7 +1,12 @@ - - + + + + + - + + + @@ -13,10 +18,9 @@ - + - - + diff --git a/AnimatedPaths/Base.lproj/Main.storyboard b/AnimatedPaths/Base.lproj/Main.storyboard index 3e7afb4..9e9193c 100644 --- a/AnimatedPaths/Base.lproj/Main.storyboard +++ b/AnimatedPaths/Base.lproj/Main.storyboard @@ -1,8 +1,12 @@ - - + + + + + - + + @@ -14,28 +18,25 @@ - + - + - - - - - - - + + - + + + @@ -46,17 +47,20 @@ - + + + + - + diff --git a/AnimatedPaths/RCAnimatedPath.swift b/AnimatedPaths/RCAnimatedPath.swift index dbf7806..c320515 100644 --- a/AnimatedPaths/RCAnimatedPath.swift +++ b/AnimatedPaths/RCAnimatedPath.swift @@ -13,25 +13,15 @@ import CoreGraphics -class RCAnimatedPath -{ - //////////////////////// - // CREATE A SINGLETON // +class RCAnimatedPath{ - class var shared: RCAnimatedPath - { - struct Singleton - { + class var shared: RCAnimatedPath{ + struct Singleton{ static let instance = RCAnimatedPath() } return Singleton.instance } - // CREATE A SINGLETON // - //////////////////////// - - - var animationLayer: CALayer? var pathLayer: CAShapeLayer? @@ -50,15 +40,13 @@ class RCAnimatedPath - func drawAnimatedCustomPath(in view: UIView, path: CGPath, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor) - { + func drawAnimatedCustomPath(in view: UIView, path: CGPath, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor){ self.inputDuration = duration self.inputLineWidth = lineWidth self.inputLineColor = lineColor self.inputPath = path animationLayer = CALayer() - animationLayer?.frame = CGRect(x: 0, y: 0, width: view.layer.bounds.width, height: view.layer.bounds.height) view.layer.addSublayer(animationLayer!) view.clipsToBounds = true @@ -67,8 +55,7 @@ class RCAnimatedPath startAnimation() } - func drawAnimatedRectanglePath(in view: UIView, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor) - { + func drawAnimatedRectanglePath(in view: UIView, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor){ self.inputDuration = duration self.inputLineWidth = lineWidth self.inputLineColor = lineColor @@ -85,8 +72,7 @@ class RCAnimatedPath startAnimation() } - func drawAnimatedPolygonPath(in view: UIView, numberOfSides polygonSidesNumber: Int?, rotationAngle: CGFloat?, polygonCornerRadius: Float?, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor) - { + func drawAnimatedPolygonPath(in view: UIView, numberOfSides polygonSidesNumber: Int?, rotationAngle: CGFloat?, polygonCornerRadius: Float?, duration: CFTimeInterval, lineWidth: CGFloat, lineColor: UIColor){ self.inputDuration = duration self.inputLineWidth = lineWidth self.inputLineColor = lineColor @@ -114,8 +100,7 @@ class RCAnimatedPath startAnimation() } - func drawAnimatedText(in view: UIView, with text: String, duration: CFTimeInterval, lineWidth: CGFloat, textColor: UIColor, fontName: String?, fontSize: CGFloat?) - { + func drawAnimatedText(in view: UIView, with text: String, duration: CFTimeInterval, lineWidth: CGFloat, textColor: UIColor, fontName: String?, fontSize: CGFloat?){ self.inputText = text self.inputDuration = duration self.inputLineWidth = lineWidth @@ -138,14 +123,12 @@ class RCAnimatedPath } - func setupDrawingLayer() - { + func setupDrawingLayer(){ clearLayer() if let _ = animationLayer { - let pathRect: CGRect = animationLayer!.bounds - + let pathRect: CGRect = animationLayer!.bounds.insetBy(dx: 100.0, dy: 100.0) let pathShapeLayer = CAShapeLayer() pathShapeLayer.frame = animationLayer!.bounds @@ -163,8 +146,7 @@ class RCAnimatedPath } } - func setupTextLayer(in view: UIView) - { + func setupTextLayer(in view: UIView){ clearLayer() if let _ = animationLayer @@ -219,20 +201,34 @@ class RCAnimatedPath } - private func startAnimation() - { + private func startAnimation(){ pathLayer?.removeAllAnimations() - let pathAnimation = CABasicAnimation(keyPath: "strokeEnd") - pathAnimation.duration = inputDuration - pathAnimation.fromValue = 0.0 - pathAnimation.toValue = 1.0 - pathLayer?.add(pathAnimation, forKey: "strokeEnd") +// let pathAnimation = CABasicAnimation(keyPath: "strokeEnd") +// pathAnimation.duration = inputDuration +// pathAnimation.fromValue = 0.0 +// pathAnimation.toValue = 1.0 +// pathLayer?.add(pathAnimation, forKey: "strokeEnd") + + + + let animation = CABasicAnimation(keyPath: "strokeEnd") + + animation.fromValue = 0.0 + animation.byValue = 1.0 + animation.toValue = 1.0 + animation.duration = inputDuration + + animation.fillMode = kCAFillModeForwards + animation.isRemovedOnCompletion = false + + pathLayer?.add(animation, forKey: "drawLineAnimation") + + } //freezes the animation until clearLayer() is called - func stopAnimatingWithPause() - { + func stopAnimatingWithPause(){ if let pausedTime = pathLayer?.convertTime(CACurrentMediaTime(), from: nil) { pathLayer?.speed = 0.0 @@ -241,13 +237,11 @@ class RCAnimatedPath } //clears the animation layers - func stopAnimatingWithClear() - { + func stopAnimatingWithClear(){ clearLayer() } - func clearLayer() - { + func clearLayer(){ if let _ = pathLayer { pathLayer?.removeFromSuperlayer() @@ -255,11 +249,7 @@ class RCAnimatedPath } } - - /// CREATE PATH /// - - private func rectanglePath(view: UIView) -> CGPath - { + private func rectanglePath(view: UIView) -> CGPath{ //start point - left-down corner var point = CGPoint(x: inputLineWidth/2, y: 0) let path = UIBezierPath() @@ -285,8 +275,7 @@ class RCAnimatedPath return path.cgPath } - private func polygonPath(view: UIView) -> CGPath - { + private func polygonPath(view: UIView) -> CGPath{ let path = UIBezierPath() let theta = Float(2.0 * .pi) / Float(inputPolygonSidesNumber) @@ -295,8 +284,7 @@ class RCAnimatedPath var length = squareWidth - Float(inputLineWidth) - if inputPolygonSidesNumber % 4 != 0 - { + if inputPolygonSidesNumber % 4 != 0{ length = length * cosf(theta / 2.0) + offset / 2.0 } @@ -306,8 +294,7 @@ class RCAnimatedPath var angle = Float(Double.pi) path.move(to: point) - for _ in 0 ..< inputPolygonSidesNumber - { + for _ in 0 ..< inputPolygonSidesNumber{ let x = Float(point.x) + (sideLength - offset * 2.0) * cosf(angle) let y = Float(point.y) + (sideLength - offset * 2.0) * sinf(angle) diff --git a/AnimatedPaths/ViewController.swift b/AnimatedPaths/ViewController.swift index 9f47f15..6e4b202 100644 --- a/AnimatedPaths/ViewController.swift +++ b/AnimatedPaths/ViewController.swift @@ -7,202 +7,93 @@ // import UIKit -import QuartzCore -import CoreText -import CoreGraphics -class ViewController: UIViewController, CAAnimationDelegate { - - var animationLayer: CALayer? - var pathLayer: CAShapeLayer? - var penLayer: CALayer? +class ViewController: UIViewController { + @IBOutlet weak var Segment: UISegmentedControl! + override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. - - let targetView: UIView = self.view - - RCAnimatedPath().drawAnimatedRectanglePath(in: targetView, duration: 10, lineWidth: 20, lineColor: UIColor.red) - - RCAnimatedPath().drawAnimatedPolygonPath(in: targetView, numberOfSides: 8, rotationAngle: 30, polygonCornerRadius: 8, duration: 10, lineWidth: 5, lineColor: UIColor.gray) - - RCAnimatedPath().drawAnimatedText(in: targetView, with: "K E G", duration: 10, lineWidth: 2, textColor: UIColor.blue, fontName: "anyFontName", fontSize: 50) - -// RCAnimatedPath().drawAnimatedCustomPath(in: targetView, path: myPath, duration: 15, lineWidth: 5, lineColor: UIColor.blue) - - RCAnimatedPath.shared.drawAnimatedRectanglePath(in: targetView, duration: 10, lineWidth: 20, lineColor: UIColor.red) - - -// animationLayer = CALayer() -// animationLayer?.frame = CGRect(x: 20.0, y: 40.0, width: self.view.layer.bounds.width - 40.0, height: self.view.layer.bounds.height - 84.0) -// self.view.layer.addSublayer(animationLayer!) -// -// setupDrawingLayer() -// startAnimation() - } - - func clearLayer() { - if let _ = pathLayer{ - penLayer?.removeFromSuperlayer() - pathLayer?.removeFromSuperlayer() - penLayer = nil - pathLayer = nil - } } - - func setupPenLayer() { - let penImage = UIImage(named: "noun_project_347_2")! - let pensLayer = CALayer() - pensLayer.contents = penImage.cgImage - pensLayer.anchorPoint = CGPoint.zero - pensLayer.frame = CGRect(x: 0.0, y: 0.0, width: penImage.size.width, height: penImage.size.height) - pathLayer?.addSublayer(pensLayer) - - penLayer = pensLayer - - } - - func setupDrawingLayer() { - - clearLayer() - - if let _ = animationLayer{ - let pathRect: CGRect = animationLayer!.bounds.insetBy(dx: 100.0, dy: 100.0) - let bottomLeft = CGPoint(x: pathRect.minX, y: pathRect.minY) - let topLeft = CGPoint(x: pathRect.minX, y: pathRect.minY + pathRect.height * 2.0 / 3.0) - let bottomRight = CGPoint(x: pathRect.maxX, y: pathRect.minY) - let topRight = CGPoint(x: pathRect.maxX, y: pathRect.minY + pathRect.height * 2.0 / 3.0) - let roofTip = CGPoint(x: pathRect.midX, y: pathRect.maxY) - - let path = UIBezierPath() - path.move(to: bottomLeft) - path.addLine(to: topLeft) - path.addLine(to: roofTip) - path.addLine(to: topRight) - path.addLine(to: topLeft) - path.addLine(to: bottomRight) - path.addLine(to: topRight) - path.addLine(to: bottomLeft) - path.addLine(to: bottomRight) - - let pathShapeLayer = CAShapeLayer() - pathShapeLayer.frame = animationLayer!.bounds - pathShapeLayer.bounds = pathRect - pathShapeLayer.isGeometryFlipped = true - pathShapeLayer.path = path.cgPath - pathShapeLayer.strokeColor = UIColor.black.cgColor - pathShapeLayer.fillColor = nil - pathShapeLayer.lineWidth = 10.0 - pathShapeLayer.lineJoin = kCALineJoinBevel - - animationLayer!.addSublayer(pathShapeLayer) - - pathLayer = pathShapeLayer - } - - setupPenLayer() - } - - - - func setupTextLayer() { - clearLayer() - - let font = CTFontCreateWithName("PingFangSC-Light" as CFString, 120, nil) - let attrStr = NSAttributedString(string: "Hello Swift", attributes: [kCTFontAttributeName as String: font]) - let line = CTLineCreateWithAttributedString(attrStr) - let runArray = CTLineGetGlyphRuns(line) - - let letters = CGMutablePath() - - for runIndex in 0..