From aa30c5a987bf420388a2f7c92ad7b10318689301 Mon Sep 17 00:00:00 2001 From: Masayuki Ono Date: Sun, 21 May 2017 12:57:00 +0900 Subject: [PATCH 1/3] =?UTF-8?q?Revert=20"Change=20to=20AnimatablePathView?= =?UTF-8?q?=20class=20from=20HasAnimatablePath=20protocol=F0=9F=99=87"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NativePopup/Animatable/Animatable.swift | 4 ++-- NativePopup/Animatable/AnimatableCrossView.swift | 5 +++-- NativePopup/Animatable/AnimatableDoneView.swift | 5 +++-- NativePopup/Animatable/HasAnimatableLayer.swift | 6 +++--- NativePopup/Animatable/HasAnimatablePath.swift | 13 ++++++++----- NativePopup/NativePopup.swift | 2 +- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/NativePopup/Animatable/Animatable.swift b/NativePopup/Animatable/Animatable.swift index 0c8b781..638b3fc 100644 --- a/NativePopup/Animatable/Animatable.swift +++ b/NativePopup/Animatable/Animatable.swift @@ -8,11 +8,11 @@ import Foundation -protocol Animatable { +public protocol Animatable { func animate() var duration: TimeInterval { get } } -extension Animatable { +public extension Animatable { var duration: TimeInterval { return 0.3 } } diff --git a/NativePopup/Animatable/AnimatableCrossView.swift b/NativePopup/Animatable/AnimatableCrossView.swift index dc8585d..42d799d 100644 --- a/NativePopup/Animatable/AnimatableCrossView.swift +++ b/NativePopup/Animatable/AnimatableCrossView.swift @@ -8,9 +8,10 @@ import Foundation -class AnimatableCrossView: AnimatablePathView { +class AnimatableCrossView: UIView, HasAnimatablePath { + let animatableLayer = CAShapeLayer() var duration: TimeInterval { return 0.4 } - override var animatablePath: UIBezierPath { + var path: UIBezierPath { let length = frame.width let path = UIBezierPath() path.move(to: CGPoint(x: length * 0.1, y: length * 0.1)) diff --git a/NativePopup/Animatable/AnimatableDoneView.swift b/NativePopup/Animatable/AnimatableDoneView.swift index 1f5ee32..e47dd99 100644 --- a/NativePopup/Animatable/AnimatableDoneView.swift +++ b/NativePopup/Animatable/AnimatableDoneView.swift @@ -8,8 +8,9 @@ import Foundation -class AnimatableDoneView: AnimatablePathView { - override var animatablePath: UIBezierPath { +class AnimatableDoneView: UIView, HasAnimatablePath { + let animatableLayer = CAShapeLayer() + var path: UIBezierPath { let length = frame.width let path = UIBezierPath() path.move(to: CGPoint(x: length * 0.196, y: length * 0.527)) diff --git a/NativePopup/Animatable/HasAnimatableLayer.swift b/NativePopup/Animatable/HasAnimatableLayer.swift index a676dbe..459fc67 100644 --- a/NativePopup/Animatable/HasAnimatableLayer.swift +++ b/NativePopup/Animatable/HasAnimatableLayer.swift @@ -8,12 +8,12 @@ import Foundation -protocol HasAnimatableLayer: Animatable { +public protocol HasAnimatableLayer: Animatable { var animatableLayer: CAShapeLayer { get } } -extension HasAnimatableLayer { - func animate() { +public extension HasAnimatableLayer { + public func animate() { let animation = CABasicAnimation(keyPath: "strokeEnd") animation.duration = duration animation.fromValue = 0 diff --git a/NativePopup/Animatable/HasAnimatablePath.swift b/NativePopup/Animatable/HasAnimatablePath.swift index 36e2440..75f0c29 100644 --- a/NativePopup/Animatable/HasAnimatablePath.swift +++ b/NativePopup/Animatable/HasAnimatablePath.swift @@ -8,11 +8,14 @@ import Foundation -open class AnimatablePathView: UIView, HasAnimatableLayer { - let animatableLayer = CAShapeLayer() - open var animatablePath: UIBezierPath { fatalError("Should be overridden.") } - func setupLayer() { - animatableLayer.path = animatablePath.cgPath +public protocol HasAnimatablePath: HasAnimatableLayer { + var path: UIBezierPath { get } + func setupLayer() +} + +public extension HasAnimatablePath where Self: UIView { + public func setupLayer() { + animatableLayer.path = path.cgPath animatableLayer.fillColor = UIColor.clear.cgColor animatableLayer.strokeColor = tintColor.cgColor animatableLayer.lineWidth = 9 diff --git a/NativePopup/NativePopup.swift b/NativePopup/NativePopup.swift index 1a3ad92..2fb6ede 100644 --- a/NativePopup/NativePopup.swift +++ b/NativePopup/NativePopup.swift @@ -110,7 +110,7 @@ public class NativePopup: UIView { [self, effectView, imageView, titleLabel, messageLabel].forEach { $0.translatesAutoresizingMaskIntoConstraints = false } - if let animatable = imageView as? AnimatablePathView { + if let animatable = imageView as? HasAnimatablePath { imageView.layoutIfNeeded() animatable.setupLayer() } From 84830f1ac61f5f8b4dca20b1133265905883c0c1 Mon Sep 17 00:00:00 2001 From: Masayuki Ono Date: Sun, 21 May 2017 12:58:24 +0900 Subject: [PATCH 2/3] Rename to animatablePath --- NativePopup/Animatable/AnimatableCrossView.swift | 2 +- NativePopup/Animatable/AnimatableDoneView.swift | 2 +- NativePopup/Animatable/HasAnimatablePath.swift | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NativePopup/Animatable/AnimatableCrossView.swift b/NativePopup/Animatable/AnimatableCrossView.swift index 42d799d..15ee8d7 100644 --- a/NativePopup/Animatable/AnimatableCrossView.swift +++ b/NativePopup/Animatable/AnimatableCrossView.swift @@ -11,7 +11,7 @@ import Foundation class AnimatableCrossView: UIView, HasAnimatablePath { let animatableLayer = CAShapeLayer() var duration: TimeInterval { return 0.4 } - var path: UIBezierPath { + var animatablePath: UIBezierPath { let length = frame.width let path = UIBezierPath() path.move(to: CGPoint(x: length * 0.1, y: length * 0.1)) diff --git a/NativePopup/Animatable/AnimatableDoneView.swift b/NativePopup/Animatable/AnimatableDoneView.swift index e47dd99..5428aee 100644 --- a/NativePopup/Animatable/AnimatableDoneView.swift +++ b/NativePopup/Animatable/AnimatableDoneView.swift @@ -10,7 +10,7 @@ import Foundation class AnimatableDoneView: UIView, HasAnimatablePath { let animatableLayer = CAShapeLayer() - var path: UIBezierPath { + var animatablePath: UIBezierPath { let length = frame.width let path = UIBezierPath() path.move(to: CGPoint(x: length * 0.196, y: length * 0.527)) diff --git a/NativePopup/Animatable/HasAnimatablePath.swift b/NativePopup/Animatable/HasAnimatablePath.swift index 75f0c29..6f91377 100644 --- a/NativePopup/Animatable/HasAnimatablePath.swift +++ b/NativePopup/Animatable/HasAnimatablePath.swift @@ -9,13 +9,13 @@ import Foundation public protocol HasAnimatablePath: HasAnimatableLayer { - var path: UIBezierPath { get } + var animatablePath: UIBezierPath { get } func setupLayer() } public extension HasAnimatablePath where Self: UIView { public func setupLayer() { - animatableLayer.path = path.cgPath + animatableLayer.path = animatablePath.cgPath animatableLayer.fillColor = UIColor.clear.cgColor animatableLayer.strokeColor = tintColor.cgColor animatableLayer.lineWidth = 9 From eb4fdf66f6f53542460f380fe3f3bd085175773d Mon Sep 17 00:00:00 2001 From: Masayuki Ono Date: Sun, 21 May 2017 13:27:36 +0900 Subject: [PATCH 3/3] Refactor HasAnimatablePath --- Example/ViewController.swift | 12 +++++++++ NativePopup.xcodeproj/project.pbxproj | 12 +++------ NativePopup/Animatable/Animatable.swift | 1 - .../Animatable/HasAnimatableLayer.swift | 25 ----------------- .../Animatable/HasAnimatablePath.swift | 27 +++++++++++++------ NativePopup/NativePopup.swift | 3 ++- 6 files changed, 37 insertions(+), 43 deletions(-) delete mode 100644 NativePopup/Animatable/HasAnimatableLayer.swift diff --git a/Example/ViewController.swift b/Example/ViewController.swift index b8a85e4..d07d231 100644 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -64,3 +64,15 @@ class ViewController: UIViewController { } } +class AnimatableDoneView2: UIView, HasAnimatablePath { + let animatableLayer = CAShapeLayer() + var animatablePath: UIBezierPath { + let length = frame.width + let path = UIBezierPath() + path.move(to: CGPoint(x: length * 0.196, y: length * 0.527)) + path.addLine(to: CGPoint(x: length * 0.47, y: length * 0.777)) + path.addLine(to: CGPoint(x: length * 0.99, y: length * 0.25)) + return path + } +} + diff --git a/NativePopup.xcodeproj/project.pbxproj b/NativePopup.xcodeproj/project.pbxproj index b2752e9..9dae418 100644 --- a/NativePopup.xcodeproj/project.pbxproj +++ b/NativePopup.xcodeproj/project.pbxproj @@ -8,14 +8,13 @@ /* Begin PBXBuildFile section */ FE4CECF61ED1171400D5DB31 /* AnimatableCrossView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE4CECF51ED1171400D5DB31 /* AnimatableCrossView.swift */; }; - FE4CECF81ED119F800D5DB31 /* HasAnimatablePath.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE4CECF71ED119F800D5DB31 /* HasAnimatablePath.swift */; }; FE8533901EAC7C92004BB756 /* NativePopup.h in Headers */ = {isa = PBXBuildFile; fileRef = FE85338E1EAC7C92004BB756 /* NativePopup.h */; settings = {ATTRIBUTES = (Public, ); }; }; FEB0316D1ECFF6770039A1C6 /* Preset.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB0316C1ECFF6770039A1C6 /* Preset.swift */; }; FEB031711ECFF6A30039A1C6 /* Bundle.extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB031701ECFF6A30039A1C6 /* Bundle.extension.swift */; }; FEB031731ECFF6E00039A1C6 /* InitialEffectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB031721ECFF6E00039A1C6 /* InitialEffectType.swift */; }; FEB031751ECFFB6C0039A1C6 /* Animatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB031741ECFFB6C0039A1C6 /* Animatable.swift */; }; FEB031771ECFFE120039A1C6 /* AnimatableDoneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB031761ECFFE120039A1C6 /* AnimatableDoneView.swift */; }; - FEB031791ED014D70039A1C6 /* HasAnimatableLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB031781ED014D70039A1C6 /* HasAnimatableLayer.swift */; }; + FEB031791ED014D70039A1C6 /* HasAnimatablePath.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB031781ED014D70039A1C6 /* HasAnimatablePath.swift */; }; FECA87BA1EAC7CCF00D07CB1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FECA87B91EAC7CCF00D07CB1 /* AppDelegate.swift */; }; FECA87BC1EAC7CCF00D07CB1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FECA87BB1EAC7CCF00D07CB1 /* ViewController.swift */; }; FECA87BF1EAC7CCF00D07CB1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FECA87BD1EAC7CCF00D07CB1 /* Main.storyboard */; }; @@ -57,7 +56,6 @@ /* Begin PBXFileReference section */ FE4CECF51ED1171400D5DB31 /* AnimatableCrossView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatableCrossView.swift; sourceTree = ""; }; - FE4CECF71ED119F800D5DB31 /* HasAnimatablePath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HasAnimatablePath.swift; sourceTree = ""; }; FE85338B1EAC7C92004BB756 /* NativePopup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NativePopup.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FE85338E1EAC7C92004BB756 /* NativePopup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativePopup.h; sourceTree = ""; }; FE85338F1EAC7C92004BB756 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -66,7 +64,7 @@ FEB031721ECFF6E00039A1C6 /* InitialEffectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitialEffectType.swift; sourceTree = ""; }; FEB031741ECFFB6C0039A1C6 /* Animatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animatable.swift; sourceTree = ""; }; FEB031761ECFFE120039A1C6 /* AnimatableDoneView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatableDoneView.swift; sourceTree = ""; }; - FEB031781ED014D70039A1C6 /* HasAnimatableLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HasAnimatableLayer.swift; sourceTree = ""; }; + FEB031781ED014D70039A1C6 /* HasAnimatablePath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HasAnimatablePath.swift; sourceTree = ""; }; FECA87B71EAC7CCF00D07CB1 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; FECA87B91EAC7CCF00D07CB1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; FECA87BB1EAC7CCF00D07CB1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -105,8 +103,7 @@ isa = PBXGroup; children = ( FEB031741ECFFB6C0039A1C6 /* Animatable.swift */, - FEB031781ED014D70039A1C6 /* HasAnimatableLayer.swift */, - FE4CECF71ED119F800D5DB31 /* HasAnimatablePath.swift */, + FEB031781ED014D70039A1C6 /* HasAnimatablePath.swift */, FE4CECF51ED1171400D5DB31 /* AnimatableCrossView.swift */, FEB031761ECFFE120039A1C6 /* AnimatableDoneView.swift */, ); @@ -293,10 +290,9 @@ FEB031711ECFF6A30039A1C6 /* Bundle.extension.swift in Sources */, FEB031731ECFF6E00039A1C6 /* InitialEffectType.swift in Sources */, FEB031771ECFFE120039A1C6 /* AnimatableDoneView.swift in Sources */, - FEB031791ED014D70039A1C6 /* HasAnimatableLayer.swift in Sources */, + FEB031791ED014D70039A1C6 /* HasAnimatablePath.swift in Sources */, FEB031751ECFFB6C0039A1C6 /* Animatable.swift in Sources */, FECA87E31EACC7F000D07CB1 /* UIImageConvertible.swift in Sources */, - FE4CECF81ED119F800D5DB31 /* HasAnimatablePath.swift in Sources */, FECA87F21EADBA3C00D07CB1 /* Extension.swift in Sources */, FECA87D81EAC7D9E00D07CB1 /* NativePopup.swift in Sources */, FEB0316D1ECFF6770039A1C6 /* Preset.swift in Sources */, diff --git a/NativePopup/Animatable/Animatable.swift b/NativePopup/Animatable/Animatable.swift index 638b3fc..a7b3629 100644 --- a/NativePopup/Animatable/Animatable.swift +++ b/NativePopup/Animatable/Animatable.swift @@ -10,7 +10,6 @@ import Foundation public protocol Animatable { func animate() - var duration: TimeInterval { get } } public extension Animatable { diff --git a/NativePopup/Animatable/HasAnimatableLayer.swift b/NativePopup/Animatable/HasAnimatableLayer.swift deleted file mode 100644 index 459fc67..0000000 --- a/NativePopup/Animatable/HasAnimatableLayer.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// HasAnimatableLayer.swift -// NativePopup -// -// Created by mono on 2017/05/20. -// Copyright © 2017 mono. All rights reserved. -// - -import Foundation - -public protocol HasAnimatableLayer: Animatable { - var animatableLayer: CAShapeLayer { get } -} - -public extension HasAnimatableLayer { - public func animate() { - let animation = CABasicAnimation(keyPath: "strokeEnd") - animation.duration = duration - animation.fromValue = 0 - animation.toValue = 1 - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) - animatableLayer.strokeEnd = 1 - animatableLayer.add(animation, forKey: "animation") - } -} diff --git a/NativePopup/Animatable/HasAnimatablePath.swift b/NativePopup/Animatable/HasAnimatablePath.swift index 6f91377..8b67fdb 100644 --- a/NativePopup/Animatable/HasAnimatablePath.swift +++ b/NativePopup/Animatable/HasAnimatablePath.swift @@ -1,27 +1,38 @@ // -// HasAnimatablePath.swift +// HasAnimatableLayer.swift // NativePopup // -// Created by mono on 2017/05/21. +// Created by mono on 2017/05/20. // Copyright © 2017 mono. All rights reserved. // import Foundation -public protocol HasAnimatablePath: HasAnimatableLayer { +public protocol HasAnimatablePath: Animatable { + var layer: CALayer { get } + var tintColor: UIColor! { get } + /** Should return same instance */ + var animatableLayer: CAShapeLayer { get } var animatablePath: UIBezierPath { get } - func setupLayer() } -public extension HasAnimatablePath where Self: UIView { - public func setupLayer() { +public extension HasAnimatablePath { + public func animate() { + let animation = CABasicAnimation(keyPath: "strokeEnd") + animation.duration = duration + animation.fromValue = 0 + animation.toValue = 1 + animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + animatableLayer.strokeEnd = 1 + animatableLayer.add(animation, forKey: "animation") + } + public func configureAnimatableLayer() { animatableLayer.path = animatablePath.cgPath animatableLayer.fillColor = UIColor.clear.cgColor - animatableLayer.strokeColor = tintColor.cgColor + animatableLayer.strokeColor = tintColor?.cgColor animatableLayer.lineWidth = 9 animatableLayer.lineCap = kCALineCapRound animatableLayer.lineJoin = kCALineCapRound animatableLayer.strokeEnd = 0 - layer.addSublayer(animatableLayer) } } diff --git a/NativePopup/NativePopup.swift b/NativePopup/NativePopup.swift index 2fb6ede..ff491d8 100644 --- a/NativePopup/NativePopup.swift +++ b/NativePopup/NativePopup.swift @@ -112,7 +112,8 @@ public class NativePopup: UIView { if let animatable = imageView as? HasAnimatablePath { imageView.layoutIfNeeded() - animatable.setupLayer() + animatable.configureAnimatableLayer() + animatable.layer.addSublayer(animatable.animatableLayer) } }