Commit 9fd0e15e by Daniel Dahan

progression update for latest internal changes in Motion

parent 3bc0ad78
...@@ -30,7 +30,7 @@ import UIKit ...@@ -30,7 +30,7 @@ import UIKit
public protocol MotionAnimator: class { public protocol MotionAnimator: class {
/// A reference to Motion. /// A reference to Motion.
weak var motion: Motion! { get set } weak var motion: MotionTransition! { get set }
/// Cleans the contexts. /// Cleans the contexts.
func clean() func clean()
...@@ -68,8 +68,8 @@ public protocol MotionAnimator: class { ...@@ -68,8 +68,8 @@ public protocol MotionAnimator: class {
/** /**
Applies the given state to the given view. Applies the given state to the given view.
- Parameter state: A MotionTransitionState. - Parameter state: A MotionModifier.
- Parameter to view: A UIView. - Parameter to view: A UIView.
*/ */
func apply(state: MotionTransitionState, to view: UIView) func apply(state: MotionTargetState, to view: UIView)
} }
...@@ -36,7 +36,7 @@ internal class MotionAnimatorViewContext { ...@@ -36,7 +36,7 @@ internal class MotionAnimatorViewContext {
var snapshot: UIView var snapshot: UIView
/// The animation target state. /// The animation target state.
var targetState: MotionTransitionState var targetState: MotionTargetState
/// A boolean indicating if the view is appearing. /// A boolean indicating if the view is appearing.
var isAppearing: Bool var isAppearing: Bool
...@@ -58,10 +58,10 @@ internal class MotionAnimatorViewContext { ...@@ -58,10 +58,10 @@ internal class MotionAnimatorViewContext {
An initializer. An initializer.
- Parameter animator: A MotionAnimator. - Parameter animator: A MotionAnimator.
- Parameter snapshot: A UIView. - Parameter snapshot: A UIView.
- Parameter targetState: A MotionTransitionState. - Parameter targetState: A MotionModifier.
- Parameter isAppearing: A Boolean. - Parameter isAppearing: A Boolean.
*/ */
required init(animator: MotionCoreAnimator, snapshot: UIView, targetState: MotionTransitionState, isAppearing: Bool) { required init(animator: MotionCoreAnimator, snapshot: UIView, targetState: MotionTargetState, isAppearing: Bool) {
self.animator = animator self.animator = animator
self.snapshot = snapshot self.snapshot = snapshot
self.targetState = targetState self.targetState = targetState
...@@ -77,11 +77,11 @@ internal class MotionAnimatorViewContext { ...@@ -77,11 +77,11 @@ internal class MotionAnimatorViewContext {
A class function that determines if a view can be animated A class function that determines if a view can be animated
to a given state. to a given state.
- Parameter view: A UIView. - Parameter view: A UIView.
- Parameter state: A MotionTransitionState. - Parameter state: A MotionModifier.
- Parameter isAppearing: A boolean that determines whether the - Parameter isAppearing: A boolean that determines whether the
view is appearing. view is appearing.
*/ */
class func canAnimate(view: UIView, state: MotionTransitionState, isAppearing: Bool) -> Bool { class func canAnimate(view: UIView, state: MotionTargetState, isAppearing: Bool) -> Bool {
return false return false
} }
...@@ -106,9 +106,9 @@ internal class MotionAnimatorViewContext { ...@@ -106,9 +106,9 @@ internal class MotionAnimatorViewContext {
/** /**
Applies the given state to the target state. Applies the given state to the target state.
- Parameter state: A MotionTransitionState. - Parameter state: A MotionModifier.
*/ */
func apply(state: MotionTransitionState) {} func apply(state: MotionTargetState) {}
/** /**
Starts the animations with an appearing boolean flag. Starts the animations with an appearing boolean flag.
......
...@@ -30,7 +30,7 @@ import UIKit ...@@ -30,7 +30,7 @@ import UIKit
internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext { internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext {
/// The transition states. /// The transition states.
fileprivate var transitionStates = [String: (Any?, Any?)]() fileprivate var state = [String: (Any?, Any?)]()
/// A reference to the animation timing function. /// A reference to the animation timing function.
fileprivate var timingFunction = CAMediaTimingFunction.standard fileprivate var timingFunction = CAMediaTimingFunction.standard
...@@ -51,7 +51,7 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext { ...@@ -51,7 +51,7 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext {
overlayLayer = nil overlayLayer = nil
} }
override class func canAnimate(view: UIView, state: MotionTransitionState, isAppearing: Bool) -> Bool { override class func canAnimate(view: UIView, state: MotionTargetState, isAppearing: Bool) -> Bool {
return nil != state.position || return nil != state.position ||
nil != state.size || nil != state.size ||
nil != state.transform || nil != state.transform ||
...@@ -70,13 +70,13 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext { ...@@ -70,13 +70,13 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext {
state.forceAnimate state.forceAnimate
} }
override func apply(state: MotionTransitionState) { override func apply(state: MotionTargetState) {
let targetState = viewState(targetState: state) let targetState = viewState(targetState: state)
for (key, targetValue) in targetState { for (key, targetValue) in targetState {
if nil == transitionStates[key] { if nil == state[key] {
let current = currentValue(for: key) let current = currentValue(for: key)
transitionStates[key] = (current, current) state[key] = (current, current)
} }
let oldAnimations = animations let oldAnimations = animations
...@@ -87,8 +87,8 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext { ...@@ -87,8 +87,8 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext {
} }
override func resume(at elapsedTime: TimeInterval, isReversed: Bool) -> TimeInterval { override func resume(at elapsedTime: TimeInterval, isReversed: Bool) -> TimeInterval {
for (key, (fromValue, toValue)) in transitionStates { for (key, (fromValue, toValue)) in state {
transitionStates[key] = (currentValue(for: key), isReversed ? fromValue : toValue) state[key] = (currentValue(for: key), isReversed ? fromValue : toValue)
} }
if isReversed { if isReversed {
...@@ -125,28 +125,31 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext { ...@@ -125,28 +125,31 @@ internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext {
} }
override func startAnimations() -> TimeInterval { override func startAnimations() -> TimeInterval {
if let beginState = targetState.beginState?.state { if let beginStateModifiers = targetState.beginState {
let beginState = MotionTargetState(modifiers: beginStateModifiers)
let appeared = viewState(targetState: beginState) let appeared = viewState(targetState: beginState)
for (k, v) in appeared { for (k, v) in appeared {
snapshot.layer.setValue(v, forKeyPath: k) snapshot.layer.setValue(v, forKeyPath: k)
} }
if let (k, v) = beginState.overlay { if let (color, opacity) = beginState.overlay {
let overlay = getOverlayLayer() let overlay = getOverlayLayer()
overlay.backgroundColor = k overlay.backgroundColor = color
overlay.opacity = Float(v) overlay.opacity = Float(opacity)
} }
} }
let disappeared = viewState(targetState: targetState) let disappeared = viewState(targetState: targetState)
for (k, v) in disappeared {
let isAppearingState = currentValue(for: k) for (k, disappearedState) in disappeared {
let toValue = isAppearing ? isAppearingState : v let appearingState = currentValue(for: k)
let fromValue = !isAppearing ? isAppearingState : v let toValue = isAppearing ? appearingState : disappearedState
let fromValue = !isAppearing ? appearingState : disappearedState
transitionStates[k] = (fromValue, toValue) state[k] = (fromValue, toValue)
} }
return animate(delay: targetState.delay, duration: duration) return animate(delay: targetState.delay, duration: duration)
} }
} }
...@@ -416,7 +419,7 @@ fileprivate extension MotionCoreAnimationViewContext { ...@@ -416,7 +419,7 @@ fileprivate extension MotionCoreAnimationViewContext {
animations = [] animations = []
for (key, (fromValue, toValue)) in transitionStates { for (key, (fromValue, toValue)) in state {
let neededTime = animate(key: key, beginTime: currentTime + delay, duration: duration, fromValue: fromValue, toValue: toValue) let neededTime = animate(key: key, beginTime: currentTime + delay, duration: duration, fromValue: fromValue, toValue: toValue)
timeUntilStop = max(timeUntilStop, neededTime) timeUntilStop = max(timeUntilStop, neededTime)
} }
...@@ -426,10 +429,10 @@ fileprivate extension MotionCoreAnimationViewContext { ...@@ -426,10 +429,10 @@ fileprivate extension MotionCoreAnimationViewContext {
/** /**
Constructs a map of key paths to animation state values. Constructs a map of key paths to animation state values.
- Parameter targetState state: A MotionTransitionState. - Parameter targetState state: A MotionModifier.
- Returns: A map of key paths to animation values. - Returns: A map of key paths to animation values.
*/ */
func viewState(targetState ts: MotionTransitionState) -> [String: Any?] { func viewState(targetState ts: MotionTargetState) -> [String: Any?] {
var ts = ts var ts = ts
var values = [String: Any?]() var values = [String: Any?]()
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
import UIKit import UIKit
class MotionCoreAnimator: MotionAnimator { class MotionCoreAnimator: MotionAnimator {
weak public var motion: Motion! weak public var motion: MotionTransition!
/// A reference to the MotionContext. /// A reference to the MotionContext.
public var context: MotionContext! { public var context: MotionContext! {
...@@ -52,7 +52,7 @@ class MotionCoreAnimator: MotionAnimator { ...@@ -52,7 +52,7 @@ class MotionCoreAnimator: MotionAnimator {
return 0 return 0
} }
func apply(state: MotionTransitionState, to view: UIView) {} func apply(state: MotionTargetState, to view: UIView) {}
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
import UIKit import UIKit
internal class MotionTransitionAnimator<T: MotionAnimatorViewContext>: MotionCoreAnimator { internal class MotionTargetStateAnimator<T: MotionAnimatorViewContext>: MotionCoreAnimator {
/// An index of views to their corresponding animator context. /// An index of views to their corresponding animator context.
var viewToContexts = [UIView: T]() var viewToContexts = [UIView: T]()
...@@ -132,10 +132,10 @@ internal class MotionTransitionAnimator<T: MotionAnimatorViewContext>: MotionCor ...@@ -132,10 +132,10 @@ internal class MotionTransitionAnimator<T: MotionAnimatorViewContext>: MotionCor
/** /**
Applies the given state to the given view. Applies the given state to the given view.
- Parameter state: A MotionTransitionState. - Parameter state: A MotionModifier.
- Parameter to view: A UIView. - Parameter to view: A UIView.
*/ */
override func apply(state: MotionTransitionState, to view: UIView) { override func apply(state: MotionTargetState, to view: UIView) {
guard let v = viewToContexts[view] else { guard let v = viewToContexts[view] else {
return return
} }
...@@ -144,7 +144,7 @@ internal class MotionTransitionAnimator<T: MotionAnimatorViewContext>: MotionCor ...@@ -144,7 +144,7 @@ internal class MotionTransitionAnimator<T: MotionAnimatorViewContext>: MotionCor
} }
} }
fileprivate extension MotionTransitionAnimator { fileprivate extension MotionTargetStateAnimator {
/** /**
Creates a view context for a given view. Creates a view context for a given view.
- Parameter view: A UIView. - Parameter view: A UIView.
......
...@@ -39,7 +39,7 @@ internal class MotionViewPropertyViewContext: MotionAnimatorViewContext { ...@@ -39,7 +39,7 @@ internal class MotionViewPropertyViewContext: MotionAnimatorViewContext {
/// Starting effect. /// Starting effect.
fileprivate var startEffect: UIVisualEffect? fileprivate var startEffect: UIVisualEffect?
override class func canAnimate(view: UIView, state: MotionTransitionState, isAppearing: Bool) -> Bool { override class func canAnimate(view: UIView, state: MotionTargetState, isAppearing: Bool) -> Bool {
return view is UIVisualEffectView && nil != state.opacity return view is UIVisualEffectView && nil != state.opacity
} }
......
...@@ -43,8 +43,8 @@ fileprivate struct AssociatedInstance { ...@@ -43,8 +43,8 @@ fileprivate struct AssociatedInstance {
/// An optional reference to the motion animations. /// An optional reference to the motion animations.
fileprivate var animations: [MotionAnimation]? fileprivate var animations: [MotionAnimation]?
/// An optional reference to the motion transition animations. /// An optional reference to the motion animation modifiers.
fileprivate var transitions: [MotionTransition]? fileprivate var modifiers: [MotionModifier]?
/// An alpha value. /// An alpha value.
fileprivate var alpha: CGFloat? fileprivate var alpha: CGFloat?
...@@ -55,7 +55,7 @@ fileprivate extension UIView { ...@@ -55,7 +55,7 @@ fileprivate extension UIView {
fileprivate var associatedInstance: AssociatedInstance { fileprivate var associatedInstance: AssociatedInstance {
get { get {
return AssociatedObject.get(base: self, key: &AssociatedInstanceKey) { return AssociatedObject.get(base: self, key: &AssociatedInstanceKey) {
return AssociatedInstance(isEnabled: true, isEnabledForSubviews: true, identifier: nil, animations: nil, transitions: nil, alpha: 1) return AssociatedInstance(isEnabled: true, isEnabledForSubviews: true, identifier: nil, animations: nil, modifiers: nil, alpha: 1)
} }
} }
set(value) { set(value) {
...@@ -136,30 +136,30 @@ public extension UIView { ...@@ -136,30 +136,30 @@ public extension UIView {
} }
/** /**
A function that accepts a list of MotionTransition values. A function that accepts a list of MotionTargetState values.
- Parameter transitions: A list of MotionTransition values. - Parameter transitions: A list of MotionTargetState values.
*/ */
func transition(_ transitions: MotionTransition...) { func transition(_ modifiers: MotionModifier...) {
transition(transitions) transition(modifiers)
} }
/** /**
A function that accepts an Array of MotionTransition values. A function that accepts an Array of MotionTargetState values.
- Parameter transitions: An Array of MotionTransition values. - Parameter transitions: An Array of MotionTargetState values.
*/ */
func transition(_ transitions: [MotionTransition]) { func transition(_ modifiers: [MotionModifier]) {
motionTransitions = transitions motionModifiers = modifiers
} }
} }
internal extension UIView { internal extension UIView {
/// The animations to run while in transition. /// The animations to run while in transition.
var motionTransitions: [MotionTransition]? { var motionModifiers: [MotionModifier]? {
get { get {
return associatedInstance.transitions return associatedInstance.modifiers
} }
set(value) { set(value) {
associatedInstance.transitions = value associatedInstance.modifiers = value
} }
} }
...@@ -286,10 +286,10 @@ internal extension UIView { ...@@ -286,10 +286,10 @@ internal extension UIView {
/** /**
Calculates the optimized duration for a view. Calculates the optimized duration for a view.
- Parameter targetState: A MotionTransitionState. - Parameter targetState: A MotionTargetState.
- Returns: A TimeInterval. - Returns: A TimeInterval.
*/ */
func optimizedDuration(targetState: MotionTransitionState) -> TimeInterval { func optimizedDuration(targetState: MotionTargetState) -> TimeInterval {
return optimizedDuration(position: targetState.position, return optimizedDuration(position: targetState.position,
size: targetState.size, size: targetState.size,
transform: targetState.transform) transform: targetState.transform)
......
...@@ -32,13 +32,13 @@ fileprivate var AssociatedInstanceKey: UInt8 = 0 ...@@ -32,13 +32,13 @@ fileprivate var AssociatedInstanceKey: UInt8 = 0
fileprivate struct AssociatedInstance { fileprivate struct AssociatedInstance {
/// A reference to the modal animation. /// A reference to the modal animation.
var modalTransitionType: MotionTransitionType var modalTransitionType: MotionTransitionAnimationType
/// A reference to the navigation animation. /// A reference to the navigation animation.
var navigationTransitionType: MotionTransitionType var navigationTransitionType: MotionTransitionAnimationType
/// A reference to the tabBar animation. /// A reference to the tabBar animation.
var tabBarTransitionType: MotionTransitionType var tabBarTransitionType: MotionTransitionAnimationType
/// A reference to the stored snapshot. /// A reference to the stored snapshot.
var storedSnapshot: UIView? var storedSnapshot: UIView?
...@@ -75,7 +75,7 @@ extension UIViewController { ...@@ -75,7 +75,7 @@ extension UIViewController {
} }
/// Default motion animation type for presenting & dismissing modally. /// Default motion animation type for presenting & dismissing modally.
public var motionTransitionType: MotionTransitionType { public var motionTransitionType: MotionTransitionAnimationType {
get { get {
return associatedInstance.modalTransitionType return associatedInstance.modalTransitionType
} }
...@@ -161,7 +161,7 @@ extension UIViewController { ...@@ -161,7 +161,7 @@ extension UIViewController {
extension UINavigationController { extension UINavigationController {
/// Default motion animation type for push and pop within the navigation controller. /// Default motion animation type for push and pop within the navigation controller.
public var motionNavigationTransitionType: MotionTransitionType { public var motionNavigationTransitionType: MotionTransitionAnimationType {
get { get {
return associatedInstance.navigationTransitionType return associatedInstance.navigationTransitionType
} }
...@@ -173,7 +173,7 @@ extension UINavigationController { ...@@ -173,7 +173,7 @@ extension UINavigationController {
extension UITabBarController { extension UITabBarController {
/// Default motion animation type for switching tabs within the tab bar controller. /// Default motion animation type for switching tabs within the tab bar controller.
public var motionTabBarTransitionType: MotionTransitionType { public var motionTabBarTransitionType: MotionTransitionAnimationType {
get { get {
return associatedInstance.tabBarTransitionType return associatedInstance.tabBarTransitionType
} }
......
...@@ -45,7 +45,7 @@ public class MotionContext { ...@@ -45,7 +45,7 @@ public class MotionContext {
internal var viewToAlphas = [UIView: CGFloat]() internal var viewToAlphas = [UIView: CGFloat]()
/// A reference of view to transition target state. /// A reference of view to transition target state.
internal var viewToTargetState = [UIView: MotionTransitionState]() internal var viewToTargetState = [UIView: MotionTargetState]()
/// A reference of the superview to the subviews snapshots. /// A reference of the superview to the subviews snapshots.
internal var superviewToNoSnapshotSubviewMap = [UIView: [(Int, UIView)]]() internal var superviewToNoSnapshotSubviewMap = [UIView: [(Int, UIView)]]()
...@@ -94,14 +94,21 @@ internal extension MotionContext { ...@@ -94,14 +94,21 @@ internal extension MotionContext {
for v in views { for v in views {
v.layer.removeAllAnimations() v.layer.removeAllAnimations()
if container.convert(v.bounds, from: v).intersects(container.bounds) { let targetState: MotionTargetState?
if let i = v.motionIdentifier {
identifierMap[i] = v if let modifiers = v.motionModifiers {
} targetState = MotionTargetState(modifiers: modifiers)
if let i = v.motionTransitions { } else {
viewToTargetState[v] = MotionTransitionState(transitions: i) targetState = nil
}
if true == targetState?.forceAnimate || container.convert(v.bounds, from: v).intersects(container.bounds) {
if let motionIdentifier = v.motionIdentifier {
identifierMap[motionIdentifier] = v
} }
viewToTargetState[v] = targetState
} }
} }
} }
...@@ -110,11 +117,11 @@ internal extension MotionContext { ...@@ -110,11 +117,11 @@ internal extension MotionContext {
public extension MotionContext { public extension MotionContext {
/** /**
A subscript that takes a given view and retrieves a A subscript that takes a given view and retrieves a
MotionTransitionState if one exists. MotionModifier if one exists.
- Parameter view: A UIView. - Parameter view: A UIView.
- Returns: An optional MotionTransitionState. - Returns: An optional MotionTargetState.
*/ */
subscript(view: UIView) -> MotionTransitionState? { subscript(view: UIView) -> MotionTargetState? {
get { get {
return viewToTargetState[view] return viewToTargetState[view]
} }
......
...@@ -125,27 +125,32 @@ class MotionPlugin: MotionCorePreprocessor, MotionAnimator { ...@@ -125,27 +125,32 @@ class MotionPlugin: MotionCorePreprocessor, MotionAnimator {
- state: the target state to override - state: the target state to override
- view: the view to override - view: the view to override
*/ */
open func apply(state: MotionTransitionState, to view: UIView) {} open func apply(state: MotionTargetState, to view: UIView) {}
} }
// methods for enable/disable the current plugin // methods for enable/disable the current plugin
extension MotionPlugin { extension MotionPlugin {
public static var isEnabled: Bool { /// A boolean indicating whether plugins are available.
get { public static var isEnabled: Bool {
return Motion.isEnabled(plugin: self) get {
return MotionTransition.isEnabled(plugin: self)
}
set(value) {
if value {
enable()
} else {
disable()
}
}
} }
set {
if newValue { /// Enable plugins.
enable() public static func enable() {
} else { MotionTransition.enable(plugin: self)
disable() }
}
/// Disable plugins.
public static func disable() {
MotionTransition.disable(plugin: self)
} }
}
public static func enable() {
Motion.enable(plugin: self)
}
public static func disable() {
Motion.disable(plugin: self)
}
} }
/*
* The MIT License (MIT)
*
* Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>.
* All rights reserved.
*
* Original Inspiration & Author
* Copyright (c) 2016 Luke Zhao <me@lkzhao.com>
*
* 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.
*/
@objc(MotionState)
public enum MotionState: Int {
/// Motion is able to start a new transition.
case possible
/// UIKit has notified Motion about a pending transition.
/// Motion hasn't started preparation.
case notified
/// Motion's `start` method has been called. Preparing the animation.
case starting
/// Motions's `animate` method has been called. Animation has started.
case animating
/// Motions's `complete` method has been called. Transition has ended or has
/// been cancelled. Motion is cleaning up.
case completing
}
...@@ -28,29 +28,12 @@ ...@@ -28,29 +28,12 @@
import UIKit import UIKit
internal class MotionTransitionStateWrapper { public struct MotionTargetState {
/// A reference to a MotionTransitionState.
internal var state: MotionTransitionState
/**
An initializer that accepts a given MotionTransitionState.
- Parameter state: A MotionTransitionState.
*/
internal init(state: MotionTransitionState) {
self.state = state
}
}
public struct MotionTransitionState {
/// The initial state that the transition will start at. /// The initial state that the transition will start at.
internal var beginState: MotionTransitionStateWrapper? internal var beginState: [MotionModifier]?
public var conditionalModifiers: [((MotionConditionalContext) -> Bool, [MotionModifier])]?
public var conditionalTransitions: [((MotionConditionalContext) -> Bool, [MotionTransition])]?
/// The start state if there is a match in the desition view controller.
public var beginStateIfMatched: [MotionTransition]?
/// A reference to the position. /// A reference to the position.
public var position: CGPoint? public var position: CGPoint?
...@@ -154,29 +137,29 @@ public struct MotionTransitionState { ...@@ -154,29 +137,29 @@ public struct MotionTransitionState {
public var custom: [String: Any]? public var custom: [String: Any]?
/** /**
An initializer that accepts an Array of MotionTransitions. An initializer that accepts an Array of MotionTargetStates.
- Parameter transitions: An Array of MotionTransitions. - Parameter transitions: An Array of MotionTargetStates.
*/ */
init(transitions: [MotionTransition]) { init(modifiers: [MotionModifier]) {
append(contentsOf: transitions) append(contentsOf: modifiers)
} }
} }
extension MotionTransitionState { extension MotionTargetState {
/** /**
Adds a MotionTransition to the current state. Adds a MotionTargetState to the current state.
- Parameter _ element: A MotionTransition. - Parameter _ modifier: A MotionTargetState.
*/ */
public mutating func append(_ element: MotionTransition) { public mutating func append(_ modifier: MotionModifier) {
element.apply(&self) modifier.apply(&self)
} }
/** /**
Adds an Array of MotionTransitions to the current state. Adds an Array of MotionTargetStates to the current state.
- Parameter contentsOf elements: An Array of MotionTransitions. - Parameter contentsOf modifiers: An Array of MotionTargetStates.
*/ */
public mutating func append(contentsOf elements: [MotionTransition]) { public mutating func append(contentsOf modifiers: [MotionModifier]) {
for v in elements { for v in modifiers {
v.apply(&self) v.apply(&self)
} }
} }
...@@ -200,12 +183,12 @@ extension MotionTransitionState { ...@@ -200,12 +183,12 @@ extension MotionTransitionState {
} }
} }
extension MotionTransitionState: ExpressibleByArrayLiteral { extension MotionTargetState: ExpressibleByArrayLiteral {
/** /**
An initializer implementing the ExpressibleByArrayLiteral protocol. An initializer implementing the ExpressibleByArrayLiteral protocol.
- Parameter arrayLiteral elements: A list of MotionTransitions. - Parameter arrayLiteral elements: A list of MotionTargetStates.
*/ */
public init(arrayLiteral elements: MotionTransition...) { public init(arrayLiteral elements: MotionModifier...) {
append(contentsOf: elements) append(contentsOf: elements)
} }
} }
...@@ -28,11 +28,11 @@ ...@@ -28,11 +28,11 @@
import Foundation import Foundation
public protocol MotionTransitionObserver { public protocol MotionTargetStateObserver {
/** /**
Executed when the elapsed time changes during a transition. Executed when the elapsed time changes during a transition.
- Parameter transitionObserver: A MotionTransitionObserver. - Parameter transitionObserver: A MotionTargetStateObserver.
- Parameter didUpdateWith elapsedTime: A TimeInterval. - Parameter didUpdateWith elapsedTime: A TimeInterval.
*/ */
func motion(transitionObserver: MotionTransitionObserver, didUpdateWith elapsedTime: TimeInterval) func motion(transitionObserver: MotionTargetStateObserver, didUpdateWith elapsedTime: TimeInterval)
} }
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
import UIKit import UIKit
public struct MotionConditionalContext { public struct MotionConditionalContext {
internal weak var motion: Motion! internal weak var motion: MotionTransition!
public weak var view: UIView! public weak var view: UIView!
public private(set) var isAppearing: Bool public private(set) var isAppearing: Bool
...@@ -97,11 +97,11 @@ class ConditionalPreprocessor: MotionCorePreprocessor { ...@@ -97,11 +97,11 @@ class ConditionalPreprocessor: MotionCorePreprocessor {
func process(views: [UIView], isAppearing: Bool) { func process(views: [UIView], isAppearing: Bool) {
for v in views { for v in views {
guard let conditionalTransitions = context[v]?.conditionalTransitions else { guard let conditionalModifiers = context[v]?.conditionalModifiers else {
continue continue
} }
for (condition, transitions) in conditionalTransitions { for (condition, transitions) in conditionalModifiers {
if condition(MotionConditionalContext(motion: motion, view: v, isAppearing: isAppearing)) { if condition(MotionConditionalContext(motion: motion, view: v, isAppearing: isAppearing)) {
context[v]!.append(contentsOf: transitions) context[v]!.append(contentsOf: transitions)
} }
......
...@@ -40,8 +40,8 @@ class MatchPreprocessor: MotionCorePreprocessor { ...@@ -40,8 +40,8 @@ class MatchPreprocessor: MotionCorePreprocessor {
continue continue
} }
var tvState = context[tv] ?? MotionTransitionState() var tvState = context[tv] ?? MotionTargetState()
var fvState = context[fv] ?? MotionTransitionState() var fvState = context[fv] ?? MotionTargetState()
// match is just a two-way source effect // match is just a two-way source effect
tvState.motionIdentifier = motionIdentifier tvState.motionIdentifier = motionIdentifier
......
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
import UIKit import UIKit
class MotionCorePreprocessor: MotionPreprocessor { class MotionCorePreprocessor: MotionPreprocessor {
weak public var motion: Motion! weak public var motion: MotionTransition!
/// A reference to the MotionContext. /// A reference to the MotionContext.
public var context: MotionContext! { public var context: MotionContext! {
return motion?.context return motion!.context
} }
func process(fromViews: [UIView], toViews: [UIView]) {} func process(fromViews: [UIView], toViews: [UIView]) {}
......
...@@ -30,7 +30,7 @@ import UIKit ...@@ -30,7 +30,7 @@ import UIKit
public protocol MotionPreprocessor: class { public protocol MotionPreprocessor: class {
/// A reference to Motion. /// A reference to Motion.
weak var motion: Motion! { get set } weak var motion: MotionTransition! { get set }
/** /**
Processes the transitionary views. Processes the transitionary views.
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
import UIKit import UIKit
public enum MotionTransitionType { public enum MotionTransitionAnimationType {
public enum Direction { public enum Direction {
case left case left
case right case right
...@@ -50,19 +50,19 @@ public enum MotionTransitionType { ...@@ -50,19 +50,19 @@ public enum MotionTransitionType {
case zoom case zoom
case zoomOut case zoomOut
indirect case selectBy(presenting: MotionTransitionType, dismissing: MotionTransitionType) indirect case selectBy(presenting: MotionTransitionAnimationType, dismissing: MotionTransitionAnimationType)
/** /**
Sets the presenting and dismissing transitions. Sets the presenting and dismissing transitions.
- Parameter presenting: A MotionTransitionType. - Parameter presenting: A MotionTransitionAnimationType.
- Returns: A MotionTransitionType. - Returns: A MotionTransitionAnimationType.
*/ */
public static func autoReverse(presenting: MotionTransitionType) -> MotionTransitionType { public static func autoReverse(presenting: MotionTransitionAnimationType) -> MotionTransitionAnimationType {
return .selectBy(presenting: presenting, dismissing: presenting.reversed()) return .selectBy(presenting: presenting, dismissing: presenting.reversed())
} }
/// Returns a reversal transition. /// Returns a reversal transition.
func reversed() -> MotionTransitionType { func reversed() -> MotionTransitionAnimationType {
switch self { switch self {
case .push(direction: .up): case .push(direction: .up):
return .pull(direction: .down) return .pull(direction: .down)
...@@ -218,7 +218,9 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -218,7 +218,9 @@ class TransitionPreprocessor: MotionCorePreprocessor {
} }
if case .auto = defaultAnimation { if case .auto = defaultAnimation {
if animators.contains(where: { $0.canAnimate(view: tv, isAppearing: true) || $0.canAnimate(view: fv, isAppearing: false) }) { if animators.contains(where: {
$0.canAnimate(view: tv, isAppearing: true) || $0.canAnimate(view: fv, isAppearing: false)
}) {
defaultAnimation = .none defaultAnimation = .none
} else if isNavigationController { } else if isNavigationController {
...@@ -239,14 +241,16 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -239,14 +241,16 @@ class TransitionPreprocessor: MotionCorePreprocessor {
context[fv] = [.timingFunction(.standard), .duration(0.35)] context[fv] = [.timingFunction(.standard), .duration(0.35)]
context[tv] = [.timingFunction(.standard), .duration(0.35)] context[tv] = [.timingFunction(.standard), .duration(0.35)]
let shadowState: [MotionTransition] = [.shadow(opacity: 0.5), let shadowState: [MotionModifier] = [.shadow(opacity: 0.5),
.shadow(color: .black), .shadow(color: .black),
.shadow(radius: 5), .shadow(radius: 5),
.shadow(offset: .zero), .shadow(offset: .zero),
.masksToBounds(false)] .masksToBounds(false)]
switch defaultAnimation { switch defaultAnimation {
case .push(let direction): case .push(let direction):
context.insertToViewFirst = false
context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)),
.shadow(opacity: 0), .shadow(opacity: 0),
.beginWith(transitions: shadowState), .beginWith(transitions: shadowState),
...@@ -277,6 +281,8 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -277,6 +281,8 @@ class TransitionPreprocessor: MotionCorePreprocessor {
context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), .scale(0.8)]) context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), .scale(0.8)])
case .cover(let direction): case .cover(let direction):
context.insertToViewFirst = false
context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)),
.shadow(opacity: 0), .shadow(opacity: 0),
.beginWith(transitions: shadowState), .beginWith(transitions: shadowState),
...@@ -295,6 +301,8 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -295,6 +301,8 @@ class TransitionPreprocessor: MotionCorePreprocessor {
context[tv]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1)]) context[tv]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1)])
case .pageIn(let direction): case .pageIn(let direction):
context.insertToViewFirst = false
context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)),
.shadow(opacity: 0), .shadow(opacity: 0),
.beginWith(transitions: shadowState), .beginWith(transitions: shadowState),
...@@ -333,10 +341,13 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -333,10 +341,13 @@ class TransitionPreprocessor: MotionCorePreprocessor {
case .zoom: case .zoom:
context.insertToViewFirst = true context.insertToViewFirst = true
context[fv]!.append(contentsOf: [.scale(1.3), .fadeOut]) context[fv]!.append(contentsOf: [.scale(1.3), .fadeOut])
context[tv]!.append(contentsOf: [.scale(0.7)]) context[tv]!.append(contentsOf: [.scale(0.7)])
case .zoomOut: case .zoomOut:
context.insertToViewFirst = false
context[tv]!.append(contentsOf: [.scale(1.3), .fadeOut]) context[tv]!.append(contentsOf: [.scale(1.3), .fadeOut])
context[fv]!.append(contentsOf: [.scale(0.7)]) context[fv]!.append(contentsOf: [.scale(0.7)])
...@@ -347,7 +358,7 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -347,7 +358,7 @@ class TransitionPreprocessor: MotionCorePreprocessor {
/** /**
Shifts the transition by a given size. Shifts the transition by a given size.
- Parameter direction: A MotionTransitionType.Direction. - Parameter direction: A MotionTransitionAnimationType.Direction.
- Parameter isAppearing: A boolean indicating whether it is appearing - Parameter isAppearing: A boolean indicating whether it is appearing
or not. or not.
- Parameter size: An optional CGSize. - Parameter size: An optional CGSize.
...@@ -355,7 +366,7 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -355,7 +366,7 @@ class TransitionPreprocessor: MotionCorePreprocessor {
and `y` point for `x`. and `y` point for `x`.
- Returns: A CGPoint. - Returns: A CGPoint.
*/ */
func shift(direction: MotionTransitionType.Direction, isAppearing: Bool, size: CGSize? = nil, transpose: Bool = false) -> CGPoint { func shift(direction: MotionTransitionAnimationType.Direction, isAppearing: Bool, size: CGSize? = nil, transpose: Bool = false) -> CGPoint {
let size = size ?? context.container.bounds.size let size = size ?? context.container.bounds.size
let point: CGPoint let point: CGPoint
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
import UIKit import UIKit
extension Motion { extension MotionTransition {
/// Starts the transition animation. /// Starts the transition animation.
func animate() { func animate() {
guard .starting == state else { guard .starting == state else {
...@@ -85,7 +85,6 @@ extension Motion { ...@@ -85,7 +85,6 @@ extension Motion {
return animator.canAnimate(view: $0, isAppearing: true) return animator.canAnimate(view: $0, isAppearing: true)
}) })
print("T", t, "DURATION", duration)
if .infinity == duration { if .infinity == duration {
animatorWantsInteractive = true animatorWantsInteractive = true
} else { } else {
...@@ -95,12 +94,10 @@ extension Motion { ...@@ -95,12 +94,10 @@ extension Motion {
totalDuration = t totalDuration = t
print("T", t)
if let forceFinishing = forceFinishing { if let forceFinishing = forceFinishing {
complete(isFinishing: forceFinishing) complete(isFinishing: forceFinishing)
} else if let startingProgress = startingProgress { } else if let startingProgress = startingProgress {
update(elapsedTime: startingProgress) update(startingProgress)
} else if animatorWantsInteractive { } else if animatorWantsInteractive {
update(elapsedTime: 0) update(elapsedTime: 0)
} else { } else {
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
import UIKit import UIKit
extension Motion { extension MotionTransition {
/** /**
Complete the transition. Complete the transition.
- Parameter after: A TimeInterval. - Parameter after: A TimeInterval.
...@@ -36,7 +36,7 @@ extension Motion { ...@@ -36,7 +36,7 @@ extension Motion {
has completed. has completed.
*/ */
func complete(after: TimeInterval, isFinishing: Bool) { func complete(after: TimeInterval, isFinishing: Bool) {
guard [MotionState.animating, .starting, .notified].contains(state) else { guard [MotionTransitionState.animating, .starting, .notified].contains(state) else {
return return
} }
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
import UIKit import UIKit
extension Motion { extension MotionTransition {
/// Starts the transition animation. /// Starts the transition animation.
func start() { func start() {
guard .notified == state else { guard .notified == state else {
...@@ -55,7 +55,7 @@ extension Motion { ...@@ -55,7 +55,7 @@ extension Motion {
} }
} }
fileprivate extension Motion { fileprivate extension MotionTransition {
/// Prepares the views frames. /// Prepares the views frames.
func prepareViewFrame() { func prepareViewFrame() {
guard let fv = fromView else { guard let fv = fromView else {
...@@ -119,10 +119,10 @@ fileprivate extension Motion { ...@@ -119,10 +119,10 @@ fileprivate extension Motion {
/// Prepares the animators. /// Prepares the animators.
func prepareAnimators() { func prepareAnimators() {
animators.append(MotionTransitionAnimator<MotionCoreAnimationViewContext>()) animators.append(MotionTargetStateAnimator<MotionCoreAnimationViewContext>())
if #available(iOS 10, tvOS 10, *) { if #available(iOS 10, tvOS 10, *) {
animators.append(MotionTransitionAnimator<MotionViewPropertyViewContext>()) animators.append(MotionTargetStateAnimator<MotionViewPropertyViewContext>())
} }
for v in animators { for v in animators {
...@@ -132,7 +132,7 @@ fileprivate extension Motion { ...@@ -132,7 +132,7 @@ fileprivate extension Motion {
/// Prepares the plugins. /// Prepares the plugins.
func preparePlugins() { func preparePlugins() {
for x in Motion.enabledPlugins.map({ for x in MotionTransition.enabledPlugins.map({
return $0.init() return $0.init()
}) { }) {
plugins.append(x) plugins.append(x)
...@@ -162,7 +162,7 @@ fileprivate extension Motion { ...@@ -162,7 +162,7 @@ fileprivate extension Motion {
container = UIView(frame: transitionContainer?.bounds ?? .zero) container = UIView(frame: transitionContainer?.bounds ?? .zero)
if !toOverFullScreen && !fromOverFullScreen { if !toOverFullScreen && !fromOverFullScreen {
updateContainerBackgroundColor() container.backgroundColor = containerBackgroundColor
} }
transitionContainer?.addSubview(container) transitionContainer?.addSubview(container)
...@@ -243,7 +243,7 @@ fileprivate extension Motion { ...@@ -243,7 +243,7 @@ fileprivate extension Motion {
} }
} }
fileprivate extension Motion { fileprivate extension MotionTransition {
/// Executes the preprocessors' process function. /// Executes the preprocessors' process function.
func processPreprocessors() { func processPreprocessors() {
for v in preprocessors { for v in preprocessors {
......
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