diff --git a/Spring/Spring.swift b/Spring/Spring.swift index cf86e1a..b6da3bd 100644 --- a/Spring/Spring.swift +++ b/Spring/Spring.swift @@ -103,7 +103,7 @@ public class Spring : NSObject { private var transform : CGAffineTransform { get { return view.transform } set { view.transform = newValue }} private var alpha: CGFloat { get { return view.alpha } set { view.alpha = newValue } } - public enum AnimationPreset: String { + public enum AnimationPreset: String, CaseIterable { case SlideLeft = "slideLeft" case SlideRight = "slideRight" case SlideDown = "slideDown" diff --git a/Spring/Springable+Animation.swift b/Spring/Springable+Animation.swift new file mode 100644 index 0000000..69dae7c --- /dev/null +++ b/Spring/Springable+Animation.swift @@ -0,0 +1,44 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015 Meng To (meng@designcode.io) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import Foundation + +/** + An extension for convenience methods applicable to all Springable objects relating to animation. + */ +public extension Springable { + + /** + A convenience method for animating any Springable object directly with the given `Spring.AnimationPreset` with an additional optional completion handler. + + - Parameter animation: The animation type to animate from `Spring.AnimationPreset`. This will overwrite any previously set animations. + - Parameter completion: Optional completion handler for this method. Defaults to nil. + */ + func animate(withAnimation animation: Spring.AnimationPreset, + withCompletion completion: (() -> ())? = nil) { + self.animation = animation.rawValue + self.animateNext { + completion?() + } + } + +} diff --git a/SpringApp.xcodeproj/project.pbxproj b/SpringApp.xcodeproj/project.pbxproj index a0e8956..a2d9e62 100644 --- a/SpringApp.xcodeproj/project.pbxproj +++ b/SpringApp.xcodeproj/project.pbxproj @@ -49,6 +49,8 @@ 9641178C1A5BEC6F000E3A5A /* OptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964117891A5BEC6F000E3A5A /* OptionsViewController.swift */; }; 9641178D1A5BEC6F000E3A5A /* CodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9641178A1A5BEC6F000E3A5A /* CodeViewController.swift */; }; 96C5F4621AC464C800BB8A18 /* AutoTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C5F4611AC464C800BB8A18 /* AutoTextView.swift */; }; + A4C97FD6267E704900CE4095 /* Springable+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4C97FD5267E704900CE4095 /* Springable+Animation.swift */; }; + A4C97FD8267E70E700CE4095 /* Springable+AnimationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4C97FD7267E70E700CE4095 /* Springable+AnimationTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -143,6 +145,8 @@ 9641178A1A5BEC6F000E3A5A /* CodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeViewController.swift; sourceTree = ""; }; 969775D31A6AD6AC009B4B79 /* DesignableTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DesignableTabBarController.swift; sourceTree = ""; }; 96C5F4611AC464C800BB8A18 /* AutoTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoTextView.swift; sourceTree = ""; }; + A4C97FD5267E704900CE4095 /* Springable+Animation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Springable+Animation.swift"; sourceTree = ""; }; + A4C97FD7267E70E700CE4095 /* Springable+AnimationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Springable+AnimationTests.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -199,6 +203,7 @@ 1A4FDA431A6E44780099D309 /* SpringTests */ = { isa = PBXGroup; children = ( + A4C97FD7267E70E700CE4095 /* Springable+AnimationTests.swift */, 1A4FDA461A6E44780099D309 /* SpringTests.swift */, 1A4FDA441A6E44780099D309 /* Supporting Files */, ); @@ -219,21 +224,22 @@ 1AA7E1821AA36EFF00762D75 /* AsyncButton.swift */, 1AA7E1811AA36EFF00762D75 /* AsyncImageView.swift */, 96C5F4611AC464C800BB8A18 /* AutoTextView.swift */, - 1A4FDA2A1A6E44270099D309 /* LoadingView.swift */, - 1A4FDA2B1A6E44270099D309 /* LoadingView.xib */, 961888D31A66BF9000295A64 /* BlurView.swift */, 961888D51A66BF9000295A64 /* DesignableButton.swift */, 961888D61A66BF9000295A64 /* DesignableImageView.swift */, 961888D71A66BF9000295A64 /* DesignableLabel.swift */, + 969775D31A6AD6AC009B4B79 /* DesignableTabBarController.swift */, 961888D81A66BF9000295A64 /* DesignableTextField.swift */, 961888D91A66BF9000295A64 /* DesignableTextView.swift */, 961888DA1A66BF9000295A64 /* DesignableView.swift */, - 969775D31A6AD6AC009B4B79 /* DesignableTabBarController.swift */, 961888DB1A66BF9000295A64 /* ImageLoader.swift */, 1A585F3F1A7B9530007EEB7D /* KeyboardLayoutConstraint.swift */, + 1A4FDA2A1A6E44270099D309 /* LoadingView.swift */, + 1A4FDA2B1A6E44270099D309 /* LoadingView.xib */, 961888DF1A66BF9000295A64 /* Misc.swift */, 1A9F866C1A83C5640098BE6C /* SoundPlayer.swift */, 1AD08AC61A676D5800160D45 /* Spring.swift */, + A4C97FD5267E704900CE4095 /* Springable+Animation.swift */, 961888E01A66BF9000295A64 /* SpringAnimation.swift */, 961888E11A66BF9000295A64 /* SpringButton.swift */, 1AF3F11A1A6776760090E8F9 /* SpringImageView.swift */, @@ -513,6 +519,7 @@ 1A4FDA631A6E44A70099D309 /* SpringButton.swift in Sources */, 1A4FDA621A6E44A70099D309 /* SpringAnimation.swift in Sources */, 1A585F401A7B9530007EEB7D /* KeyboardLayoutConstraint.swift in Sources */, + A4C97FD6267E704900CE4095 /* Springable+Animation.swift in Sources */, 1AA7E1831AA36EFF00762D75 /* AsyncImageView.swift in Sources */, 1A4FDA6B1A6E44A70099D309 /* UnwindSegue.swift in Sources */, 1A4FDA681A6E44A70099D309 /* SpringView.swift in Sources */, @@ -528,6 +535,7 @@ buildActionMask = 2147483647; files = ( 1A4FDA471A6E44780099D309 /* SpringTests.swift in Sources */, + A4C97FD8267E70E700CE4095 /* Springable+AnimationTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SpringTests/Springable+AnimationTests.swift b/SpringTests/Springable+AnimationTests.swift new file mode 100644 index 0000000..16138b4 --- /dev/null +++ b/SpringTests/Springable+AnimationTests.swift @@ -0,0 +1,26 @@ +// +// Springable+AnimateTests.swift +// SpringAppTests +// +// Created by Joshua James Varghese on 19.06.21. +// Copyright © 2021 Meng To. All rights reserved. +// + +import Foundation +import XCTest +import Spring + +class SpringableAnimateTests: XCTestCase { + + let springView = SpringView() + + func testAnimationPropertySetCorrectly() { + for animationType in Spring.AnimationPreset.allCases { + springView.animate(withAnimation: animationType) + + XCTAssertEqual(springView.animation, animationType.rawValue) + } + } + +} +