Commit 65c3210c by Daniel Dahan

issue-2: added completion block to motion animations

parent 48064570
...@@ -235,7 +235,7 @@ extension UIView { ...@@ -235,7 +235,7 @@ extension UIView {
/** /**
Snapshots the view instance for animations during transitions. Snapshots the view instance for animations during transitions.
- Parameter afterUpdates: A boolean indicating whether to snapshot the view - Parameter afterUpdates: A boolean indicating whether to snapshot the view
after a render update, or as is. after a render update, or as is.
- Parameter shouldHide: A boolean indicating whether the view should be hidden - Parameter shouldHide: A boolean indicating whether the view should be hidden
after the snapshot is taken. after the snapshot is taken.
- Returns: A UIView instance that is a snapshot of the given UIView. - Returns: A UIView instance that is a snapshot of the given UIView.
...@@ -243,6 +243,9 @@ extension UIView { ...@@ -243,6 +243,9 @@ extension UIView {
open func transitionSnapshot(afterUpdates: Bool, shouldHide: Bool = true) -> UIView { open func transitionSnapshot(afterUpdates: Bool, shouldHide: Bool = true) -> UIView {
isHidden = false isHidden = false
// Material specific.
(self as? PulseableLayer)?.pulseLayer?.isHidden = true
let oldCornerRadius = layer.cornerRadius let oldCornerRadius = layer.cornerRadius
layer.cornerRadius = 0 layer.cornerRadius = 0
...@@ -288,6 +291,9 @@ extension UIView { ...@@ -288,6 +291,9 @@ extension UIView {
v.motionTransform = motionTransform v.motionTransform = motionTransform
v.backgroundColor = backgroundColor v.backgroundColor = backgroundColor
// Material specific.
(self as? PulseableLayer)?.pulseLayer?.isHidden = false
isHidden = shouldHide isHidden = shouldHide
return v return v
...@@ -422,9 +428,9 @@ open class Motion: NSObject { ...@@ -422,9 +428,9 @@ open class Motion: NSObject {
/** /**
An initializer to modify the presenting and container state. An initializer to modify the presenting and container state.
- Parameter isPresenting: A boolean value indicating if the - Parameter isPresenting: A boolean value indicating if the
Motion instance is presenting the view controller. Motion instance is presenting the view controller.
- Parameter isContainer: A boolean value indicating if the - Parameter isContainer: A boolean value indicating if the
Motion instance is a container view controller. Motion instance is a container view controller.
*/ */
public init(isPresenting: Bool, isContainer: Bool) { public init(isPresenting: Bool, isContainer: Bool) {
...@@ -469,7 +475,6 @@ open class Motion: NSObject { ...@@ -469,7 +475,6 @@ open class Motion: NSObject {
if !$0 { if !$0 {
DispatchQueue.main.async(execute: block) DispatchQueue.main.async(execute: block)
} }
cancelable = nil cancelable = nil
} }
...@@ -524,7 +529,6 @@ extension Motion: UIViewControllerAnimatedTransitioning { ...@@ -524,7 +529,6 @@ extension Motion: UIViewControllerAnimatedTransitioning {
@objc(animateTransition:) @objc(animateTransition:)
open func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { open func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContext = transitionContext self.transitionContext = transitionContext
fromViewController.motionDelegate?.motion?(motion: self, willTransition: fromView, toView: toView) fromViewController.motionDelegate?.motion?(motion: self, willTransition: fromView, toView: toView)
Motion.delay(delayTransitionByTimeInterval) { [weak self] in Motion.delay(delayTransitionByTimeInterval) { [weak self] in
...@@ -658,7 +662,7 @@ extension Motion { ...@@ -658,7 +662,7 @@ extension Motion {
snapshotChildGroup.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf) snapshotChildGroup.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf)
snapshot.animate(snapshotGroup) snapshot.animate(snapshotGroup)
snapshot.subviews.first!.animate(snapshotChildGroup) snapshot.subviews.first?.animate(snapshotChildGroup)
} }
} }
} }
......
...@@ -93,6 +93,9 @@ public enum MotionAnimation { ...@@ -93,6 +93,9 @@ public enum MotionAnimation {
case size(width: CGFloat, height: CGFloat) case size(width: CGFloat, height: CGFloat)
} }
@available(iOS 10, *)
extension CALayer: CAAnimationDelegate {}
extension CALayer { extension CALayer {
/** /**
...@@ -111,7 +114,10 @@ extension CALayer { ...@@ -111,7 +114,10 @@ extension CALayer {
*/ */
open func animate(_ animations: [CAAnimation]) { open func animate(_ animations: [CAAnimation]) {
for animation in animations { for animation in animations {
animation.delegate = self if nil == animation.delegate {
animation.delegate = self
}
if let a = animation as? CABasicAnimation { if let a = animation as? CABasicAnimation {
a.fromValue = (presentation() ?? self).value(forKeyPath: a.keyPath!) a.fromValue = (presentation() ?? self).value(forKeyPath: a.keyPath!)
} }
...@@ -126,6 +132,8 @@ extension CALayer { ...@@ -126,6 +132,8 @@ extension CALayer {
} }
} }
open func animationDidStart(_ anim: CAAnimation) {}
/** /**
A delegation function that is executed when the backing layer stops A delegation function that is executed when the backing layer stops
running an animation. running an animation.
...@@ -134,9 +142,9 @@ extension CALayer { ...@@ -134,9 +142,9 @@ extension CALayer {
because it was completed or interrupted. True if completed, false because it was completed or interrupted. True if completed, false
if interrupted. if interrupted.
*/ */
open func animationDidStop(_ animation: CAAnimation, finished flag: Bool) { open func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
guard let a = animation as? CAPropertyAnimation else { guard let a = anim as? CAPropertyAnimation else {
if let a = (animation as? CAAnimationGroup)?.animations { if let a = (anim as? CAAnimationGroup)?.animations {
for x in a { for x in a {
animationDidStop(x, finished: true) animationDidStop(x, finished: true)
} }
...@@ -171,9 +179,10 @@ extension CALayer { ...@@ -171,9 +179,10 @@ extension CALayer {
/** /**
A function that accepts an Array of MotionAnimation values and executes them. A function that accepts an Array of MotionAnimation values and executes them.
- Parameter animations: An Array of MotionAnimation values. - Parameter animations: An Array of MotionAnimation values.
- Parameter completion: An optional completion block.
*/ */
open func motion(_ animations: [MotionAnimation]) { open func motion(_ animations: [MotionAnimation], completion: (() -> Void)? = nil) {
motion(delay: 0, duration: 0.35, timingFunction: .easeInEaseOut, animations: animations) motion(delay: 0, duration: 0.35, timingFunction: .easeInEaseOut, animations: animations, completion: completion)
} }
/** /**
...@@ -182,8 +191,9 @@ extension CALayer { ...@@ -182,8 +191,9 @@ extension CALayer {
- Parameter duration: The animation duration TimeInterval. - Parameter duration: The animation duration TimeInterval.
- Parameter timingFunction: The animation MotionAnimationTimingFunction. - Parameter timingFunction: The animation MotionAnimationTimingFunction.
- Parameter animations: An Array of MotionAnimations. - Parameter animations: An Array of MotionAnimations.
- Parameter completion: An optional completion block.
*/ */
fileprivate func motion(delay: TimeInterval, duration: TimeInterval, timingFunction: MotionAnimationTimingFunction, animations: [MotionAnimation]) { fileprivate func motion(delay: TimeInterval, duration: TimeInterval, timingFunction: MotionAnimationTimingFunction, animations: [MotionAnimation], completion: (() -> Void)? = nil) {
var t = delay var t = delay
for v in animations { for v in animations {
...@@ -311,13 +321,16 @@ extension CALayer { ...@@ -311,13 +321,16 @@ extension CALayer {
g.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf) g.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf)
s.animate(g) s.animate(g)
guard let execute = completion else {
return
}
Motion.delay(d, execute: execute)
} }
} }
} }
@available(iOS 10, *)
extension CALayer: CAAnimationDelegate {}
extension UIView { extension UIView {
/// Computes the rotation of the view. /// Computes the rotation of the view.
open var motionRotationAngle: CGFloat { open var motionRotationAngle: CGFloat {
...@@ -385,9 +398,10 @@ extension UIView { ...@@ -385,9 +398,10 @@ extension UIView {
A function that accepts an Array of MotionAnimation values and executes A function that accepts an Array of MotionAnimation values and executes
them on the view's backing layer. them on the view's backing layer.
- Parameter animations: An Array of MotionAnimation values. - Parameter animations: An Array of MotionAnimation values.
- Parameter completion: An optional completion block.
*/ */
open func motion(_ animations: [MotionAnimation]) { open func motion(_ animations: [MotionAnimation], completion: (() -> Void)? = nil) {
layer.motion(animations) layer.motion(animations, completion: completion)
} }
} }
......
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