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) } }