Commit 486cab29 by Daniel Dahan

development: refactors Animation class

parent c97e64b6
...@@ -57,20 +57,21 @@ public func AnimationFillModeToValue(mode: AnimationFillMode) -> String { ...@@ -57,20 +57,21 @@ public func AnimationFillModeToValue(mode: AnimationFillMode) -> String {
@objc(AnimationTimingFunction) @objc(AnimationTimingFunction)
public enum AnimationTimingFunction: Int { public enum AnimationTimingFunction: Int {
case liner case linear
case easeIn case easeIn
case easeOut case easeOut
case easeInEaseOut case easeInEaseOut
case systemDefault case `default`
} }
/** /**
Converts the AnimationTimingFunction enum value to a corresponding CAMediaTimingFunction. Converts the AnimationTimingFunction enum value to a corresponding CAMediaTimingFunction.
- Parameter function: An AnimationTimingFunction enum value. - Parameter function: An AnimationTimingFunction enum value.
- Returns: A CAMediaTimingFunction.
*/ */
public func AnimationTimingFunctionToValue(function: AnimationTimingFunction) -> CAMediaTimingFunction { public func AnimationTimingFunctionToValue(function: AnimationTimingFunction) -> CAMediaTimingFunction {
switch function { switch function {
case .liner: case .linear:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
case .easeIn: case .easeIn:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
...@@ -78,18 +79,23 @@ public func AnimationTimingFunctionToValue(function: AnimationTimingFunction) -> ...@@ -78,18 +79,23 @@ public func AnimationTimingFunctionToValue(function: AnimationTimingFunction) ->
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
case .easeInEaseOut: case .easeInEaseOut:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
case .systemDefault: case .default:
return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault) return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
} }
} }
public typealias AnimationDelayCancelBlock = (Bool) -> Void public typealias AnimationDelayCancelBlock = (Bool) -> Void
public struct Animation { public struct Animation {
/// Delay helper method. /**
Executes a block of code after a time delay.
- Parameter duration: An animation duration time.
- Parameter animations: An animation block.
- Parameter execute block: A completion block that is executed once
the animations have completed.
*/
@discardableResult @discardableResult
public static func delay(time: TimeInterval, completion: @escaping () -> Void) -> AnimationDelayCancelBlock? { public static func delay(time: TimeInterval, execute block: @escaping () -> Void) -> AnimationDelayCancelBlock? {
func asyncAfter(completion: @escaping () -> Void) { func asyncAfter(completion: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time, execute: completion) DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time, execute: completion)
...@@ -97,10 +103,11 @@ public struct Animation { ...@@ -97,10 +103,11 @@ public struct Animation {
var cancelable: AnimationDelayCancelBlock? var cancelable: AnimationDelayCancelBlock?
let delayed: AnimationDelayCancelBlock = { (cancel) in let delayed: AnimationDelayCancelBlock = {
if !cancel { if !$0 {
DispatchQueue.main.async(execute: completion) DispatchQueue.main.async(execute: block)
} }
cancelable = nil cancelable = nil
} }
...@@ -114,24 +121,30 @@ public struct Animation { ...@@ -114,24 +121,30 @@ public struct Animation {
} }
/** /**
:name: delayCancel Cancels the delayed AnimationDelayCancelBlock.
- Parameter delayed completion: An AnimationDelayCancelBlock.
*/ */
public static func delayCancel(completion: AnimationDelayCancelBlock) { public static func cancel(delayed completion: AnimationDelayCancelBlock) {
completion(true) completion(true)
} }
/** /**
:name: animationDisabled Disables the default animations set on CALayers.
- Parameter animations: A callback that wraps the animations to disable.
*/ */
public static func animationDisabled(animations: (() -> Void)) { public static func disable(animations: (() -> Void)) {
animateWithDuration(duration: 0, animations: animations) animate(duration: 0, animations: animations)
} }
/** /**
:name: animateWithDuration Runs an animation with a specified duration.
- Parameter duration: An animation duration time.
- Parameter animations: An animation block.
- Parameter completion: A completion block that is executed once
the animations have completed.
*/ */
public static func animateWithDuration(duration: CFTimeInterval, animations: (() -> Void), completion: (() -> Void)? = nil) { public static func animate(duration: CFTimeInterval, animations: (() -> Void), completion: (() -> Void)? = nil) {
CATransaction.begin() CATransaction.begin()
CATransaction.setAnimationDuration(duration) CATransaction.setAnimationDuration(duration)
CATransaction.setCompletionBlock(completion) CATransaction.setCompletionBlock(completion)
...@@ -141,9 +154,12 @@ public struct Animation { ...@@ -141,9 +154,12 @@ public struct Animation {
} }
/** /**
:name: animationGroup Creates a CAAnimationGroup.
- Parameter animations: An Array of CAAnimation objects.
- Parameter duration: An animation duration time for the group.
- Returns: A CAAnimationGroup.
*/ */
public static func animationGroup(animations: [CAAnimation], duration: CFTimeInterval = 0.5) -> CAAnimationGroup { public static func animate(group animations: [CAAnimation], duration: CFTimeInterval = 0.5) -> CAAnimationGroup {
let group: CAAnimationGroup = CAAnimationGroup() let group: CAAnimationGroup = CAAnimationGroup()
group.fillMode = AnimationFillModeToValue(mode: .forwards) group.fillMode = AnimationFillModeToValue(mode: .forwards)
group.isRemovedOnCompletion = false group.isRemovedOnCompletion = false
...@@ -154,11 +170,16 @@ public struct Animation { ...@@ -154,11 +170,16 @@ public struct Animation {
} }
/** /**
:name: animateWithDelay Executes an animation block with a given delay and duration.
- Parameter delay time: A CFTimeInterval.
- Parameter duration: An animation duration time.
- Parameter animations: An animation block.
- Parameter completion: A completion block that is executed once
the animations have completed.
*/ */
public static func animateWithDelay(delay d: CFTimeInterval, duration: CFTimeInterval, animations: @escaping (() -> Void), completion: (() -> Void)? = nil) { public static func animate(delay time: CFTimeInterval, duration: CFTimeInterval, animations: @escaping (() -> Void), completion: (() -> Void)? = nil) {
delay(time: d) { delay(time: time) {
animateWithDuration(duration: duration, animations: animations, completion: completion) animate(duration: duration, animations: animations, completion: completion)
} }
} }
} }
...@@ -30,35 +30,42 @@ ...@@ -30,35 +30,42 @@
import UIKit import UIKit
public enum AnimationKey: String { public enum AnimationKeyPath: String {
case backgroundColor case backgroundColor
case cornerRadius case cornerRadius
case transform case transform
case transformRotation = "transform.rotation" case rotation = "transform.rotation"
case transformRotationX = "transform.rotation.x" case rotationX = "transform.rotation.x"
case transformRotationY = "transform.rotation.y" case rotationY = "transform.rotation.y"
case transformRotationZ = "transform.rotation.z" case rotationZ = "transform.rotation.z"
case transformScale = "transform.scale" case scale = "transform.scale"
case transformScaleX = "transform.scale.x" case scaleX = "transform.scale.x"
case transformScaleY = "transform.scale.y" case scaleY = "transform.scale.y"
case transformScaleZ = "transform.scale.z" case scaleZ = "transform.scale.z"
case transformTranslation = "transform.translation" case translation = "transform.translation"
case transformTranslationX = "transform.translation.x" case translationX = "transform.translation.x"
case transformTranslationY = "transform.translation.y" case translationY = "transform.translation.y"
case transformTranslationZ = "transform.translation.z" case translationZ = "transform.translation.z"
case position case position
case shadowPath case shadowPath
} }
extension CABasicAnimation { extension CABasicAnimation {
convenience init(keyPath key: AnimationKey) { /**
self.init(keyPath: key.rawValue) A convenience initializer that takes a given AnimationKeyPath.
- Parameter keyPath: An AnimationKeyPath.
*/
public convenience init(keyPath: AnimationKeyPath) {
self.init(keyPath: keyPath.rawValue)
} }
} }
extension Animation { extension Animation {
/** /**
:name: backgroundColor Creates a CABasicAnimation for the backgroundColor key path.
- Parameter color: A UIColor.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func backgroundColor(color: UIColor, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func backgroundColor(color: UIColor, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .backgroundColor) let animation = CABasicAnimation(keyPath: .backgroundColor)
...@@ -66,14 +73,19 @@ extension Animation { ...@@ -66,14 +73,19 @@ extension Animation {
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: cornerRadius Creates a CABasicAnimation for the cornerRadius key path.
- Parameter radius: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func cornerRadius(radius: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func cornerRadius(radius: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .cornerRadius) let animation = CABasicAnimation(keyPath: .cornerRadius)
...@@ -81,40 +93,55 @@ extension Animation { ...@@ -81,40 +93,55 @@ extension Animation {
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: translation Creates a CABasicAnimation for the transform key path.
- Parameter transform: A CATransform3D object.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func transform(transform: CATransform3D, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func transform(transform: CATransform3D, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transform) let animation = CABasicAnimation(keyPath: .transform)
animation.toValue = NSValue(caTransform3D: transform) animation.toValue = NSValue(caTransform3D: transform)
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: rotate Creates a CABasicAnimation for the transform.rotation key path.
- Parameter angle: An optional CGFloat.
- Parameter rotation: An optional CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func rotate(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func rotate(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformRotation) let animation = CABasicAnimation(keyPath: .rotation)
if let v: CGFloat = angle {
if let v = angle {
animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber
} else if let v: CGFloat = rotation { } else if let v = rotation {
animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber
} }
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
...@@ -122,67 +149,94 @@ extension Animation { ...@@ -122,67 +149,94 @@ extension Animation {
} }
/** /**
:name: rotateX Creates a CABasicAnimation for the transform.rotation.x key path.
- Parameter angle: An optional CGFloat.
- Parameter rotation: An optional CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func rotateX(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func rotateX(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformRotationX) let animation = CABasicAnimation(keyPath: .rotationX)
if let v: CGFloat = angle { if let v: CGFloat = angle {
animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber
} else if let v: CGFloat = rotation { } else if let v: CGFloat = rotation {
animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber
} }
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: rotateY Creates a CABasicAnimation for the transform.rotation.y key path.
- Parameter angle: An optional CGFloat.
- Parameter rotation: An optional CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func rotateY(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func rotateY(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformRotationY) let animation = CABasicAnimation(keyPath: .rotationY)
if let v: CGFloat = angle { if let v: CGFloat = angle {
animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber
} else if let v: CGFloat = rotation { } else if let v: CGFloat = rotation {
animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber
} }
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: rotateZ Creates a CABasicAnimation for the transform.rotation.z key path.
- Parameter angle: An optional CGFloat.
- Parameter rotation: An optional CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func rotateZ(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func rotateZ(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformRotationZ) let animation = CABasicAnimation(keyPath: .rotationZ)
if let v: CGFloat = angle { if let v: CGFloat = angle {
animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber
} else if let v: CGFloat = rotation { } else if let v: CGFloat = rotation {
animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber
} }
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: scale Creates a CABasicAnimation for the transform.scale key path.
- Parameter by scale: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func scale(scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func scale(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformScale) let animation = CABasicAnimation(keyPath: .scale)
animation.toValue = scale as NSNumber animation.toValue = scale as NSNumber
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
...@@ -194,10 +248,13 @@ extension Animation { ...@@ -194,10 +248,13 @@ extension Animation {
} }
/** /**
:name: scaleX Creates a CABasicAnimation for the transform.scale.x key path.
- Parameter by scale: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func scaleX(scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func scaleX(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformScaleX) let animation = CABasicAnimation(keyPath: .scaleX)
animation.toValue = scale as NSNumber animation.toValue = scale as NSNumber
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
...@@ -209,10 +266,13 @@ extension Animation { ...@@ -209,10 +266,13 @@ extension Animation {
} }
/** /**
:name: scaleY Creates a CABasicAnimation for the transform.scale.y key path.
- Parameter by scale: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func scaleY(scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func scaleY(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformScaleY) let animation = CABasicAnimation(keyPath: .scaleY)
animation.toValue = scale as NSNumber animation.toValue = scale as NSNumber
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
...@@ -224,10 +284,13 @@ extension Animation { ...@@ -224,10 +284,13 @@ extension Animation {
} }
/** /**
:name: scaleZ Creates a CABasicAnimation for the transform.scale.z key path.
- Parameter by scale: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func scaleZ(scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func scaleZ(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformScaleZ) let animation = CABasicAnimation(keyPath: .scaleZ)
animation.toValue = scale as NSNumber animation.toValue = scale as NSNumber
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
...@@ -239,89 +302,122 @@ extension Animation { ...@@ -239,89 +302,122 @@ extension Animation {
} }
/** /**
:name: translate Creates a CABasicAnimation for the transform.translation key path.
- Parameter size: A CGSize.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func translate(translation: CGSize, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func translation(size: CGSize, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformTranslation) let animation = CABasicAnimation(keyPath: .translation)
animation.toValue = NSValue(cgSize: translation) animation.toValue = NSValue(cgSize: size)
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: translateX Creates a CABasicAnimation for the transform.translation.x key path.
- Parameter by translation: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func translateX(translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func translationX(by translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformTranslationX) let animation = CABasicAnimation(keyPath: .translationX)
animation.toValue = translation as NSNumber animation.toValue = translation as NSNumber
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: translateY Creates a CABasicAnimation for the transform.translation.y key path.
- Parameter by translation: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func translateY(translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func translationY(by translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformTranslationY) let animation = CABasicAnimation(keyPath: .translationY)
animation.toValue = translation as NSNumber animation.toValue = translation as NSNumber
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: translateZ Creates a CABasicAnimation for the transform.translation.z key path.
- Parameter by translation: A CGFloat.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func translateZ(translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func translationZ(by translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .transformTranslationZ) let animation = CABasicAnimation(keyPath: .translationZ)
animation.toValue = translation as NSNumber animation.toValue = translation as NSNumber
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
/** /**
:name: position Creates a CABasicAnimation for the position key path.
- Parameter to point: A CGPoint.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/ */
public static func position(point: CGPoint, duration: CFTimeInterval? = nil) -> CABasicAnimation { public static func position(to point: CGPoint, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .position) let animation = CABasicAnimation(keyPath: .position)
animation.toValue = NSValue(cgPoint: point) animation.toValue = NSValue(cgPoint: point)
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
public static func shadowPath(path: CGPath, duration: CFTimeInterval? = nil) -> CABasicAnimation { /**
Creates a CABasicAnimation for the shadowPath key path.
- Parameter to path: A CGPath.
- Parameter duration: An animation time duration.
- Returns: A CABasicAnimation.
*/
public static func shadowPath(to path: CGPath, duration: CFTimeInterval? = nil) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: .shadowPath) let animation = CABasicAnimation(keyPath: .shadowPath)
animation.toValue = path animation.toValue = path
animation.fillMode = AnimationFillModeToValue(mode: .forwards) animation.fillMode = AnimationFillModeToValue(mode: .forwards)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
animation.timingFunction = AnimationTimingFunctionToValue(function: .liner) animation.timingFunction = AnimationTimingFunctionToValue(function: .linear)
if let v = duration { if let v = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
} }
...@@ -629,7 +629,7 @@ open class Capture: View, UIGestureRecognizerDelegate { ...@@ -629,7 +629,7 @@ open class Capture: View, UIGestureRecognizerDelegate {
/// Animates the tap and layer. /// Animates the tap and layer.
private func animateTap(view: UIView, point: CGPoint) { private func animateTap(view: UIView, point: CGPoint) {
// Animation.animationDisabled { [weak layer] in // Animation.disable { [weak layer] in
// guard let v = layer else { // guard let v = layer else {
// return // return
// } // }
...@@ -644,7 +644,7 @@ open class Capture: View, UIGestureRecognizerDelegate { ...@@ -644,7 +644,7 @@ open class Capture: View, UIGestureRecognizerDelegate {
// v.transform = CATransform3DMakeScale(0.5, 0.5, 1) // v.transform = CATransform3DMakeScale(0.5, 0.5, 1)
// }) { // }) {
// Animation.delay(time: 0.4) { [weak layer] in // Animation.delay(time: 0.4) { [weak layer] in
// Animation.animationDisabled { [weak layer] in // Animation.disable { [weak layer] in
// guard let v = layer else { // guard let v = layer else {
// return // return
// } // }
......
...@@ -32,17 +32,19 @@ import UIKit ...@@ -32,17 +32,19 @@ import UIKit
@objc(AnimationRotationMode) @objc(AnimationRotationMode)
public enum AnimationRotationMode: Int { public enum AnimationRotationMode: Int {
case none case `default`
case auto case auto
case autoReverse case autoReverse
} }
/** /**
:name: AnimationRotationModeToValue Converts an AnimationRotationMode to a corresponding CAAnimationRotate key.
*/ - Parameter mode: An AnimationRotationMode.
- Returns: An optional CAAnimationRotate key String.
*/
public func AnimationRotationModeToValue(mode: AnimationRotationMode) -> String? { public func AnimationRotationModeToValue(mode: AnimationRotationMode) -> String? {
switch mode { switch mode {
case .none: case .default:
return nil return nil
case .auto: case .auto:
return kCAAnimationRotateAuto return kCAAnimationRotateAuto
...@@ -53,11 +55,15 @@ public func AnimationRotationModeToValue(mode: AnimationRotationMode) -> String? ...@@ -53,11 +55,15 @@ public func AnimationRotationModeToValue(mode: AnimationRotationMode) -> String?
extension Animation { extension Animation {
/** /**
:name: path Creates a CAKeyframeAnimation.
- Parameter bezierPath: A UIBezierPath.
- Parameter mode: An AnimationRotationMode.
- Parameter duration: An animation duration time.
- Returns: A CAKeyframeAnimation.
*/ */
public static func path(bezierPath: UIBezierPath, mode: AnimationRotationMode = .auto, duration: CFTimeInterval? = nil) -> CAKeyframeAnimation { public static func path(bezierPath: UIBezierPath, mode: AnimationRotationMode = .auto, duration: CFTimeInterval? = nil) -> CAKeyframeAnimation {
let animation: CAKeyframeAnimation = CAKeyframeAnimation() let animation = CAKeyframeAnimation()
animation.keyPath = AnimationKey.position.rawValue animation.keyPath = AnimationKeyPath.position.rawValue
animation.path = bezierPath.cgPath animation.path = bezierPath.cgPath
animation.rotationMode = AnimationRotationModeToValue(mode: mode) animation.rotationMode = AnimationRotationModeToValue(mode: mode)
if let v = duration { if let v = duration {
......
...@@ -321,7 +321,7 @@ extension CALayer { ...@@ -321,7 +321,7 @@ extension CALayer {
} else if nil == shadowPath { } else if nil == shadowPath {
shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
} else { } else {
let a = Animation.shadowPath(path: UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath) let a = Animation.shadowPath(to: UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath)
a.fromValue = shadowPath a.fromValue = shadowPath
animate(animation: a) animate(animation: a)
} }
......
...@@ -71,7 +71,7 @@ internal extension Animation { ...@@ -71,7 +71,7 @@ internal extension Animation {
visualLayer.masksToBounds = !(.centerRadialBeyondBounds == pulse.animation || .radialBeyondBounds == pulse.animation) visualLayer.masksToBounds = !(.centerRadialBeyondBounds == pulse.animation || .radialBeyondBounds == pulse.animation)
Animation.animationDisabled(animations: { [visualLayer = visualLayer, pulse = pulse] in Animation.disable(animations: { [visualLayer = visualLayer, pulse = pulse] in
bLayer.frame = visualLayer.bounds bLayer.frame = visualLayer.bounds
pLayer.bounds = CGRect(x: 0, y: 0, width: n, height: n) pLayer.bounds = CGRect(x: 0, y: 0, width: n, height: n)
...@@ -99,7 +99,7 @@ internal extension Animation { ...@@ -99,7 +99,7 @@ internal extension Animation {
switch pulse.animation { switch pulse.animation {
case .center, .centerWithBacking, .centerRadialBeyondBounds, .radialBeyondBounds, .point, .pointWithBacking: case .center, .centerWithBacking, .centerRadialBeyondBounds, .radialBeyondBounds, .point, .pointWithBacking:
pLayer.add(Animation.scale(scale: 1, duration: duration), forKey: nil) pLayer.add(Animation.scale(by: 1, duration: duration), forKey: nil)
default:break default:break
} }
...@@ -138,8 +138,8 @@ internal extension Animation { ...@@ -138,8 +138,8 @@ internal extension Animation {
switch pulse.animation { switch pulse.animation {
case .center, .centerWithBacking, .centerRadialBeyondBounds, .radialBeyondBounds, .point, .pointWithBacking: case .center, .centerWithBacking, .centerRadialBeyondBounds, .radialBeyondBounds, .point, .pointWithBacking:
pLayer.add(Animation.animationGroup(animations: [ pLayer.add(Animation.animate(group: [
Animation.scale(scale: .center == pulse.animation ? 1 : 1.325), Animation.scale(by: .center == pulse.animation ? 1 : 1.325),
Animation.backgroundColor(color: pulse.color.withAlphaComponent(0)) Animation.backgroundColor(color: pulse.color.withAlphaComponent(0))
], duration: duration), forKey: nil) ], duration: duration), forKey: nil)
default:break default:break
......
...@@ -30,70 +30,78 @@ ...@@ -30,70 +30,78 @@
import UIKit import UIKit
public typealias AnimationTransitionType = String
public typealias AnimationTransitionSubTypeType = String
@objc(AnimationTransition) @objc(AnimationTransition)
public enum AnimationTransition: Int { public enum AnimationTransition: Int {
case Fade case fade
case MoveIn case moveIn
case Push case push
case Reveal case reveal
} }
@objc(AnimationTransitionSubType) @objc(AnimationTransitionDirection)
public enum AnimationTransitionSubType: Int { public enum AnimationTransitionDirection: Int {
case Right case `default`
case Left case right
case Top case left
case Bottom case top
case bottom
} }
/** /**
:name: AnimationTransitionToValue Converts an AnimationTransition to a corresponding CATransition key.
*/ - Parameter transition: An AnimationTransition.
public func AnimationTransitionToValue(transition: AnimationTransition) -> AnimationTransitionType { - Returns: A CATransition key String.
switch transition { */
case .Fade: public func AnimationTransitionToValue(transition type: AnimationTransition) -> String {
switch type {
case .fade:
return kCATransitionFade return kCATransitionFade
case .MoveIn: case .moveIn:
return kCATransitionMoveIn return kCATransitionMoveIn
case .Push: case .push:
return kCATransitionPush return kCATransitionPush
case .Reveal: case .reveal:
return kCATransitionReveal return kCATransitionReveal
} }
} }
/** /**
:name: AnimationTransitionSubTypeToValue Converts an AnimationTransitionDirection to a corresponding CATransition direction key.
*/ - Parameter direction: An AnimationTransitionDirection.
public func AnimationTransitionSubTypeToValue(direction: AnimationTransitionSubType) -> AnimationTransitionSubTypeType { - Returns: An optional CATransition direction key String.
*/
public func AnimationTransitionDirectionToValue(direction: AnimationTransitionDirection) -> String? {
switch direction { switch direction {
case .Right: case .default:
return nil
case .right:
return kCATransitionFromRight return kCATransitionFromRight
case .Left: case .left:
return kCATransitionFromLeft return kCATransitionFromLeft
case .Top: case .top:
return kCATransitionFromBottom return kCATransitionFromBottom
case .Bottom: case .bottom:
return kCATransitionFromTop return kCATransitionFromTop
} }
} }
extension Animation { extension Animation {
/** /**
:name: transition Creates a CATransition animation.
- Parameter type: An AnimationTransition.
- Parameter direction: An optional AnimationTransitionDirection.
- Parameter duration: An optional duration time.
- Returns: A CATransition.
*/ */
public static func transition(type: AnimationTransition, direction: AnimationTransitionSubType? = nil, duration: CFTimeInterval? = nil) -> CATransition { public static func transition(type: AnimationTransition, direction: AnimationTransitionDirection = .default, duration: CFTimeInterval? = nil) -> CATransition {
let animation: CATransition = CATransition() let animation = CATransition()
animation.type = AnimationTransitionToValue(transition: type) animation.type = AnimationTransitionToValue(transition: type)
if let d = direction { animation.subtype = AnimationTransitionDirectionToValue(direction: direction)
animation.subtype = AnimationTransitionSubTypeToValue(direction: d)
} if let v = duration {
if let v: CFTimeInterval = duration {
animation.duration = v animation.duration = v
} }
return animation return animation
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment