Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
Motion
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dmitriy Stepanets
Motion
Commits
fcf3d822
Unverified
Commit
fcf3d822
authored
Jun 08, 2017
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial pass at MotionController rework
parent
19664a2f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
379 additions
and
244 deletions
+379
-244
Motion.xcodeproj/project.pbxproj
+8
-4
Sources/Motion.swift
+161
-125
Sources/MotionController.swift
+172
-111
Sources/MotionTransitionObserver.swift
+38
-0
Sources/MotionViewController.swift
+0
-4
No files found.
Motion.xcodeproj/project.pbxproj
View file @
fcf3d822
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
96AEB6A31EE4610F009A3BE0
/* MotionPlugin.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB67D1EE4610F009A3BE0
/* MotionPlugin.swift */
;
};
96AEB6A31EE4610F009A3BE0
/* MotionPlugin.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB67D1EE4610F009A3BE0
/* MotionPlugin.swift */
;
};
96AEB6A41EE4610F009A3BE0
/* MotionStringConvertible.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB67E1EE4610F009A3BE0
/* MotionStringConvertible.swift */
;
};
96AEB6A41EE4610F009A3BE0
/* MotionStringConvertible.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB67E1EE4610F009A3BE0
/* MotionStringConvertible.swift */
;
};
96AEB6A51EE4610F009A3BE0
/* MotionTargetState.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB67F1EE4610F009A3BE0
/* MotionTargetState.swift */
;
};
96AEB6A51EE4610F009A3BE0
/* MotionTargetState.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB67F1EE4610F009A3BE0
/* MotionTargetState.swift */
;
};
96AEB6A61EE4610F009A3BE0
/* Motion
Types.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6801EE4610F009A3BE0
/* MotionTypes
.swift */
;
};
96AEB6A61EE4610F009A3BE0
/* Motion
ViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6801EE4610F009A3BE0
/* MotionViewController
.swift */
;
};
96AEB6A71EE4610F009A3BE0
/* Lexer.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6821EE4610F009A3BE0
/* Lexer.swift */
;
};
96AEB6A71EE4610F009A3BE0
/* Lexer.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6821EE4610F009A3BE0
/* Lexer.swift */
;
};
96AEB6A81EE4610F009A3BE0
/* Nodes.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6831EE4610F009A3BE0
/* Nodes.swift */
;
};
96AEB6A81EE4610F009A3BE0
/* Nodes.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6831EE4610F009A3BE0
/* Nodes.swift */
;
};
96AEB6A91EE4610F009A3BE0
/* Parser.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6841EE4610F009A3BE0
/* Parser.swift */
;
};
96AEB6A91EE4610F009A3BE0
/* Parser.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6841EE4610F009A3BE0
/* Parser.swift */
;
};
...
@@ -48,6 +48,7 @@
...
@@ -48,6 +48,7 @@
96AEB6AE1EE4610F009A3BE0
/* IgnoreSubviewModifiersPreprocessor.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB68A1EE4610F009A3BE0
/* IgnoreSubviewModifiersPreprocessor.swift */
;
};
96AEB6AE1EE4610F009A3BE0
/* IgnoreSubviewModifiersPreprocessor.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB68A1EE4610F009A3BE0
/* IgnoreSubviewModifiersPreprocessor.swift */
;
};
96AEB6AF1EE4610F009A3BE0
/* MatchPreprocessor.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB68B1EE4610F009A3BE0
/* MatchPreprocessor.swift */
;
};
96AEB6AF1EE4610F009A3BE0
/* MatchPreprocessor.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB68B1EE4610F009A3BE0
/* MatchPreprocessor.swift */
;
};
96AEB6B01EE4610F009A3BE0
/* SourcePreprocessor.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB68C1EE4610F009A3BE0
/* SourcePreprocessor.swift */
;
};
96AEB6B01EE4610F009A3BE0
/* SourcePreprocessor.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB68C1EE4610F009A3BE0
/* SourcePreprocessor.swift */
;
};
96E49A401EEA08F8006D5A93
/* MotionTransitionObserver.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96E49A3F1EEA08F8006D5A93
/* MotionTransitionObserver.swift */
;
};
/* End PBXBuildFile section */
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
/* Begin PBXFileReference section */
...
@@ -80,7 +81,7 @@
...
@@ -80,7 +81,7 @@
96AEB67D1EE4610F009A3BE0
/* MotionPlugin.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionPlugin.swift
;
sourceTree
=
"<group>"
;
};
96AEB67D1EE4610F009A3BE0
/* MotionPlugin.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionPlugin.swift
;
sourceTree
=
"<group>"
;
};
96AEB67E1EE4610F009A3BE0
/* MotionStringConvertible.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionStringConvertible.swift
;
sourceTree
=
"<group>"
;
};
96AEB67E1EE4610F009A3BE0
/* MotionStringConvertible.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionStringConvertible.swift
;
sourceTree
=
"<group>"
;
};
96AEB67F1EE4610F009A3BE0
/* MotionTargetState.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionTargetState.swift
;
sourceTree
=
"<group>"
;
};
96AEB67F1EE4610F009A3BE0
/* MotionTargetState.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionTargetState.swift
;
sourceTree
=
"<group>"
;
};
96AEB6801EE4610F009A3BE0
/* Motion
Types.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionTypes
.swift
;
sourceTree
=
"<group>"
;
};
96AEB6801EE4610F009A3BE0
/* Motion
ViewController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionViewController
.swift
;
sourceTree
=
"<group>"
;
};
96AEB6821EE4610F009A3BE0
/* Lexer.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Lexer.swift
;
sourceTree
=
"<group>"
;
};
96AEB6821EE4610F009A3BE0
/* Lexer.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Lexer.swift
;
sourceTree
=
"<group>"
;
};
96AEB6831EE4610F009A3BE0
/* Nodes.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Nodes.swift
;
sourceTree
=
"<group>"
;
};
96AEB6831EE4610F009A3BE0
/* Nodes.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Nodes.swift
;
sourceTree
=
"<group>"
;
};
96AEB6841EE4610F009A3BE0
/* Parser.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Parser.swift
;
sourceTree
=
"<group>"
;
};
96AEB6841EE4610F009A3BE0
/* Parser.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Parser.swift
;
sourceTree
=
"<group>"
;
};
...
@@ -95,6 +96,7 @@
...
@@ -95,6 +96,7 @@
96C98DDD1E424B9000B22906
/* Info.plist */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
text.plist.xml
;
path
=
Info.plist
;
sourceTree
=
"<group>"
;
};
96C98DDD1E424B9000B22906
/* Info.plist */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
text.plist.xml
;
path
=
Info.plist
;
sourceTree
=
"<group>"
;
};
96C98DE21E43809D00B22906
/* LICENSE */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
text
;
path
=
LICENSE
;
sourceTree
=
"<group>"
;
};
96C98DE21E43809D00B22906
/* LICENSE */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
text
;
path
=
LICENSE
;
sourceTree
=
"<group>"
;
};
96C98DED1E438A5700B22906
/* Motion.h */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
Motion.h
;
sourceTree
=
"<group>"
;
};
96C98DED1E438A5700B22906
/* Motion.h */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
Motion.h
;
sourceTree
=
"<group>"
;
};
96E49A3F1EEA08F8006D5A93
/* MotionTransitionObserver.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionTransitionObserver.swift
;
sourceTree
=
"<group>"
;
};
/* End PBXFileReference section */
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
/* Begin PBXFrameworksBuildPhase section */
...
@@ -207,7 +209,8 @@
...
@@ -207,7 +209,8 @@
96AEB67D1EE4610F009A3BE0
/* MotionPlugin.swift */
,
96AEB67D1EE4610F009A3BE0
/* MotionPlugin.swift */
,
96AEB67E1EE4610F009A3BE0
/* MotionStringConvertible.swift */
,
96AEB67E1EE4610F009A3BE0
/* MotionStringConvertible.swift */
,
96AEB67F1EE4610F009A3BE0
/* MotionTargetState.swift */
,
96AEB67F1EE4610F009A3BE0
/* MotionTargetState.swift */
,
96AEB6801EE4610F009A3BE0
/* MotionTypes.swift */
,
96AEB6801EE4610F009A3BE0
/* MotionViewController.swift */
,
96E49A3F1EEA08F8006D5A93
/* MotionTransitionObserver.swift */
,
96AEB6811EE4610F009A3BE0
/* Parser */
,
96AEB6811EE4610F009A3BE0
/* Parser */
,
96AEB6861EE4610F009A3BE0
/* Preprocessors */
,
96AEB6861EE4610F009A3BE0
/* Preprocessors */
,
);
);
...
@@ -308,9 +311,10 @@
...
@@ -308,9 +311,10 @@
96AEB6961EE4610F009A3BE0
/* Motion+CAMediaTimingFunction.swift in Sources */
,
96AEB6961EE4610F009A3BE0
/* Motion+CAMediaTimingFunction.swift in Sources */
,
96AEB6941EE4610F009A3BE0
/* Motion+Array.swift in Sources */
,
96AEB6941EE4610F009A3BE0
/* Motion+Array.swift in Sources */
,
96AEB6951EE4610F009A3BE0
/* Motion+CALayer.swift in Sources */
,
96AEB6951EE4610F009A3BE0
/* Motion+CALayer.swift in Sources */
,
96AEB6A61EE4610F009A3BE0
/* Motion
Types
.swift in Sources */
,
96AEB6A61EE4610F009A3BE0
/* Motion
ViewController
.swift in Sources */
,
96AEB68E1EE4610F009A3BE0
/* MotionCoreAnimationViewContext.swift in Sources */
,
96AEB68E1EE4610F009A3BE0
/* MotionCoreAnimationViewContext.swift in Sources */
,
96AEB6921EE4610F009A3BE0
/* MotionDebugView.swift in Sources */
,
96AEB6921EE4610F009A3BE0
/* MotionDebugView.swift in Sources */
,
96E49A401EEA08F8006D5A93
/* MotionTransitionObserver.swift in Sources */
,
96AEB6A01EE4610F009A3BE0
/* MotionIndependentController.swift in Sources */
,
96AEB6A01EE4610F009A3BE0
/* MotionIndependentController.swift in Sources */
,
96AEB6AA1EE4610F009A3BE0
/* Regex.swift in Sources */
,
96AEB6AA1EE4610F009A3BE0
/* Regex.swift in Sources */
,
96AEB6901EE4610F009A3BE0
/* MotionViewPropertyViewContext.swift in Sources */
,
96AEB6901EE4610F009A3BE0
/* MotionViewPropertyViewContext.swift in Sources */
,
...
...
Sources/Motion.swift
View file @
fcf3d822
...
@@ -58,11 +58,13 @@ public class Motion: MotionController {
...
@@ -58,11 +58,13 @@ public class Motion: MotionController {
public
internal(set)
var
isPresenting
=
true
public
internal(set)
var
isPresenting
=
true
/// Progress of the current transition, 0 if a transition is not happening.
/// Progress of the current transition, 0 if a transition is not happening.
public
override
var
progress
:
Double
{
public
override
var
elapsedTime
:
TimeInterval
{
didSet
{
didSet
{
if
isTransitioning
{
guard
isTransitioning
else
{
transitionContext
?
.
updateInteractiveTransition
(
CGFloat
(
progress
))
return
}
}
transitionContext
?
.
updateInteractiveTransition
(
CGFloat
(
elapsedTime
))
}
}
}
}
...
@@ -155,7 +157,7 @@ public extension Motion {
...
@@ -155,7 +157,7 @@ public extension Motion {
}
}
}
}
internal
extension
Motion
{
fileprivate
extension
Motion
{
/// Starts the transition animation.
/// Starts the transition animation.
func
start
()
{
func
start
()
{
guard
isTransitioning
else
{
guard
isTransitioning
else
{
...
@@ -165,51 +167,25 @@ internal extension Motion {
...
@@ -165,51 +167,25 @@ internal extension Motion {
prepareViewControllers
()
prepareViewControllers
()
prepareSnapshotView
()
prepareSnapshotView
()
prepareForTransition
()
prepareForTransition
()
prepare
Motion
Context
()
prepareContext
()
prepareToView
()
prepareToView
()
prepareViewHierarchy
()
prepareViewHierarchy
()
processContext
()
processContext
()
prepareForAnimation
()
prepareForAnimation
()
processForAnimation
()
context
.
hide
(
view
:
toView
)
#if os(tvOS)
animate
()
#else
if
isNavigationController
{
// When animating within navigationController, we have to dispatch later into the main queue.
// otherwise snapshots will be pure white. Possibly a bug with UIKit
DispatchQueue
.
main
.
async
{
[
weak
self
]
in
self
?
.
animate
()
}
}
else
{
animate
()
}
#endif
}
}
}
internal
extension
Motion
{
override
func
animate
()
{
override
func
animate
()
{
context
.
unhide
(
view
:
toView
)
context
.
unhide
(
view
:
toView
)
if
let
containerBackgroundColor
=
containerBackgroundColor
{
updateContainerBackgroundColor
()
container
.
backgroundColor
=
containerBackgroundColor
updateInsertOrder
()
}
else
if
!
toOverFullScreen
&&
!
fromOverFullScreen
{
container
.
backgroundColor
=
toView
.
backgroundColor
}
if
fromOverFullScreen
{
insertToViewFirst
=
true
}
for
animator
in
animators
{
if
let
animator
=
animator
as?
MotionHasInsertOrder
{
animator
.
insertToViewFirst
=
insertToViewFirst
}
}
super
.
animate
()
super
.
animate
()
fullScreenSnapshot
!.
removeFromSuperview
()
fullScreenSnapshot
?
.
removeFromSuperview
()
}
}
override
func
complete
(
finished
:
Bool
)
{
override
func
complete
(
finished
:
Bool
)
{
...
@@ -218,13 +194,13 @@ internal extension Motion {
...
@@ -218,13 +194,13 @@ internal extension Motion {
}
}
context
.
clean
()
context
.
clean
()
if
finished
&&
isPresenting
&&
toOverFullScreen
{
if
finished
&&
isPresenting
&&
toOverFullScreen
{
// finished presenting a overFullScreen VC
// finished presenting a overFullScreen VC
context
.
unhide
(
rootView
:
toView
)
context
.
unhide
(
rootView
:
toView
)
context
.
removeSnapshots
(
rootView
:
toView
)
context
.
removeSnapshots
(
rootView
:
toView
)
context
.
storeViewAlpha
(
rootView
:
fromView
)
context
.
storeViewAlpha
(
rootView
:
fromView
)
fromViewController
!.
motionStoredSnapshot
=
container
fromViewController
!.
motionStoredSnapshot
=
container
fromView
.
removeFromSuperview
()
fromView
.
removeFromSuperview
()
fromView
.
addSubview
(
container
)
fromView
.
addSubview
(
container
)
...
@@ -262,7 +238,7 @@ internal extension Motion {
...
@@ -262,7 +238,7 @@ internal extension Motion {
let
tContext
=
transitionContext
let
tContext
=
transitionContext
let
fvc
=
fromViewController
let
fvc
=
fromViewController
let
tvc
=
toViewController
let
tvc
=
toViewController
transitionContext
=
nil
transitionContext
=
nil
fromViewController
=
nil
fromViewController
=
nil
toViewController
=
nil
toViewController
=
nil
...
@@ -274,7 +250,7 @@ internal extension Motion {
...
@@ -274,7 +250,7 @@ internal extension Motion {
defaultAnimation
=
.
auto
defaultAnimation
=
.
auto
super
.
complete
(
finished
:
finished
)
super
.
complete
(
finished
:
finished
)
if
finished
{
if
finished
{
if
let
fvc
=
fvc
,
let
tvc
=
tvc
{
if
let
fvc
=
fvc
,
let
tvc
=
tvc
{
processForMotionDelegate
(
viewController
:
fvc
)
{
processForMotionDelegate
(
viewController
:
fvc
)
{
...
@@ -344,7 +320,7 @@ fileprivate extension Motion {
...
@@ -344,7 +320,7 @@ fileprivate extension Motion {
}
}
/// Prepares the MotionContext instance.
/// Prepares the MotionContext instance.
func
prepare
Motion
Context
()
{
func
prepareContext
()
{
context
.
loadViewAlpha
(
rootView
:
toView
)
context
.
loadViewAlpha
(
rootView
:
toView
)
context
.
loadViewAlpha
(
rootView
:
fromView
)
context
.
loadViewAlpha
(
rootView
:
fromView
)
container
.
addSubview
(
toView
)
container
.
addSubview
(
toView
)
...
@@ -370,6 +346,52 @@ internal extension Motion {
...
@@ -370,6 +346,52 @@ internal extension Motion {
super
.
prepareForTransition
()
super
.
prepareForTransition
()
insert
(
preprocessor
:
DefaultAnimationPreprocessor
(
motion
:
self
),
before
:
DurationPreprocessor
.
self
)
insert
(
preprocessor
:
DefaultAnimationPreprocessor
(
motion
:
self
),
before
:
DurationPreprocessor
.
self
)
}
}
override
func
prepareForAnimation
()
{
super
.
prepareForAnimation
()
context
.
hide
(
view
:
toView
)
}
}
fileprivate
extension
Motion
{
/// Processes the animations.
func
processForAnimation
()
{
#if os(tvOS)
animate
()
#else
if
isNavigationController
{
// When animating within navigationController, we have to dispatch later into the main queue.
// otherwise snapshots will be pure white. Possibly a bug with UIKit
DispatchQueue
.
main
.
async
{
[
weak
self
]
in
self
?
.
animate
()
}
}
else
{
animate
()
}
#endif
}
}
fileprivate
extension
Motion
{
/// Updates the container background color.
func
updateContainerBackgroundColor
()
{
if
let
v
=
containerBackgroundColor
{
container
.
backgroundColor
=
v
}
else
if
!
toOverFullScreen
&&
!
fromOverFullScreen
{
container
.
backgroundColor
=
toView
.
backgroundColor
}
}
/// Updates the insertToViewFirst boolean for animators.
func
updateInsertOrder
()
{
if
fromOverFullScreen
{
insertToViewFirst
=
true
}
for
v
in
animators
{
(
v
as?
MotionHasInsertOrder
)?
.
insertToViewFirst
=
insertToViewFirst
}
}
}
}
internal
extension
Motion
{
internal
extension
Motion
{
...
@@ -418,99 +440,113 @@ internal extension Motion {
...
@@ -418,99 +440,113 @@ internal extension Motion {
}
}
}
}
// MARK: UIKit Protocol Conformance
/*****************************
* UIKit protocol extensions *
*****************************/
extension
Motion
:
UIViewControllerAnimatedTransitioning
{
extension
Motion
:
UIViewControllerAnimatedTransitioning
{
public
func
animateTransition
(
using
context
:
UIViewControllerContextTransitioning
)
{
/**
guard
!
isTransitioning
else
{
return
}
The animation method that is used to coordinate the transition.
transitionContext
=
context
- Parameter using transitionContext: A UIViewControllerContextTransitioning.
fromViewController
=
fromViewController
??
context
.
viewController
(
forKey
:
.
from
)
*/
toViewController
=
toViewController
??
context
.
viewController
(
forKey
:
.
to
)
public
func
animateTransition
(
using
context
:
UIViewControllerContextTransitioning
)
{
transitionContainer
=
context
.
containerView
guard
!
isTransitioning
else
{
start
()
return
}
}
public
func
transitionDuration
(
using
transitionContext
:
UIViewControllerContextTransitioning
?)
->
TimeInterval
{
return
0.375
// doesn't matter, real duration will be calculated later
transitionContext
=
context
}
fromViewController
=
fromViewController
??
context
.
viewController
(
forKey
:
.
from
)
toViewController
=
toViewController
??
context
.
viewController
(
forKey
:
.
to
)
public
func
animationEnded
(
_
transitionCompleted
:
Bool
)
{
transitionContainer
=
context
.
containerView
isAnimating
=
!
transitionCompleted
}
start
()
}
/**
Returns the transition duration time interval.
- Parameter using transitionContext: An optional UIViewControllerContextTransitioning.
- Returns: A TimeInterval that is the total animation time including delays.
*/
public
func
transitionDuration
(
using
transitionContext
:
UIViewControllerContextTransitioning
?)
->
TimeInterval
{
return
0
// Will be updated dynamically.
}
public
func
animationEnded
(
_
transitionCompleted
:
Bool
)
{
isAnimating
=
!
transitionCompleted
}
}
}
extension
Motion
:
UIViewControllerTransitioningDelegate
{
extension
Motion
{
var
interactiveTransitioning
:
UIViewControllerInteractiveTransitioning
?
{
/// A reference to the interactive transitioning.
return
forceNonInteractive
?
nil
:
self
fileprivate
var
interactiveTransitioning
:
UIViewControllerInteractiveTransitioning
?
{
}
return
self
}
public
func
animationController
(
forPresented
presented
:
UIViewController
,
presenting
:
UIViewController
,
source
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
}
self
.
isPresenting
=
true
self
.
fromViewController
=
fromViewController
??
presenting
extension
Motion
:
UIViewControllerTransitioningDelegate
{
self
.
toViewController
=
toViewController
??
presented
public
func
animationController
(
forPresented
presented
:
UIViewController
,
presenting
:
UIViewController
,
source
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
return
self
self
.
isPresenting
=
true
}
self
.
fromViewController
=
fromViewController
??
presenting
self
.
toViewController
=
toViewController
??
presented
public
func
animationController
(
forDismissed
dismissed
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
return
self
self
.
isPresenting
=
false
}
self
.
fromViewController
=
fromViewController
??
dismissed
return
self
public
func
animationController
(
forDismissed
dismissed
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
}
self
.
isPresenting
=
false
self
.
fromViewController
=
fromViewController
??
dismissed
public
func
interactionControllerForDismissal
(
using
animator
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
return
self
return
interactiveTransitioning
}
}
public
func
interactionControllerForDismissal
(
using
animator
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
public
func
interactionControllerForPresentation
(
using
animator
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
return
interactiveTransitioning
return
interactiveTransitioning
}
}
public
func
interactionControllerForPresentation
(
using
animator
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
return
interactiveTransitioning
}
}
}
extension
Motion
:
UIViewControllerInteractiveTransitioning
{
extension
Motion
:
UIViewControllerInteractiveTransitioning
{
public
var
wantsInteractiveStart
:
Bool
{
public
var
wantsInteractiveStart
:
Bool
{
return
true
return
true
}
}
public
func
startInteractiveTransition
(
_
transitionContext
:
UIViewControllerContextTransitioning
)
{
public
func
startInteractiveTransition
(
_
transitionContext
:
UIViewControllerContextTransitioning
)
{
animateTransition
(
using
:
transitionContext
)
animateTransition
(
using
:
transitionContext
)
}
}
}
}
extension
Motion
:
UINavigationControllerDelegate
{
extension
Motion
:
UINavigationControllerDelegate
{
public
func
navigationController
(
_
navigationController
:
UINavigationController
,
animationControllerFor
operation
:
UINavigationControllerOperation
,
from
fromVC
:
UIViewController
,
to
toVC
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
public
func
navigationController
(
_
navigationController
:
UINavigationController
,
animationControllerFor
operation
:
UINavigationControllerOperation
,
from
fromVC
:
UIViewController
,
to
toVC
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
self
.
isPresenting
=
operation
==
.
push
self
.
isPresenting
=
.
push
==
operation
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
toViewController
=
toViewController
??
toVC
self
.
toViewController
=
toViewController
??
toVC
self
.
isNavigationController
=
true
self
.
isNavigationController
=
true
return
self
return
self
}
}
public
func
navigationController
(
_
navigationController
:
UINavigationController
,
interactionControllerFor
animationController
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
public
func
navigationController
(
_
navigationController
:
UINavigationController
,
interactionControllerFor
animationController
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
return
interactiveTransitioning
return
interactiveTransitioning
}
}
}
}
extension
Motion
:
UITabBarControllerDelegate
{
extension
Motion
:
UITabBarControllerDelegate
{
public
func
tabBarController
(
_
tabBarController
:
UITabBarController
,
shouldSelect
viewController
:
UIViewController
)
->
Bool
{
public
func
tabBarController
(
_
tabBarController
:
UITabBarController
,
shouldSelect
viewController
:
UIViewController
)
->
Bool
{
return
!
isAnimating
return
!
isAnimating
}
}
public
func
tabBarController
(
_
tabBarController
:
UITabBarController
,
interactionControllerFor
animationController
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
public
func
tabBarController
(
_
tabBarController
:
UITabBarController
,
interactionControllerFor
animationController
:
UIViewControllerAnimatedTransitioning
)
->
UIViewControllerInteractiveTransitioning
?
{
return
interactiveTransitioning
return
interactiveTransitioning
}
}
public
func
tabBarController
(
_
tabBarController
:
UITabBarController
,
animationControllerForTransitionFrom
fromVC
:
UIViewController
,
to
toVC
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
public
func
tabBarController
(
_
tabBarController
:
UITabBarController
,
animationControllerForTransitionFrom
fromVC
:
UIViewController
,
to
toVC
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
isAnimating
=
true
isAnimating
=
true
let
fromVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
fromVC
)
!
let
toVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
toVC
)
!
let
fromVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
fromVC
)
!
self
.
isPresenting
=
toVCIndex
>
fromVCIndex
let
toVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
toVC
)
!
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
toViewController
=
toViewController
??
toVC
self
.
isPresenting
=
toVCIndex
>
fromVCIndex
self
.
isTabBarController
=
true
self
.
fromViewController
=
fromViewController
??
fromVC
return
self
self
.
toViewController
=
toViewController
??
toVC
}
self
.
isTabBarController
=
true
return
self
}
}
}
public
typealias
MotionDelayCancelBlock
=
(
Bool
)
->
Void
public
typealias
MotionDelayCancelBlock
=
(
Bool
)
->
Void
...
...
Sources/MotionController.swift
View file @
fcf3d822
...
@@ -28,105 +28,166 @@
...
@@ -28,105 +28,166 @@
import
UIKit
import
UIKit
/// Base class for managing a Motion transition
public
class
MotionController
:
NSObject
{
public
class
MotionController
:
NSObject
{
// MARK: Properties
/// A reference to the MotionContext.
/// context object holding transition informations
public
internal(set)
var
context
:
MotionContext
!
public
internal(set)
var
context
:
MotionContext
!
/// whether or not we are handling transition interactively
public
var
interactive
:
Bool
{
return
displayLink
==
nil
}
/// progress of the current transition. 0 if no transition is happening
public
internal(set)
var
progress
:
Double
=
0
{
didSet
{
if
isTransitioning
{
if
let
progressUpdateObservers
=
progressUpdateObservers
{
for
observer
in
progressUpdateObservers
{
observer
.
motionDidUpdateProgress
(
progress
:
progress
)
}
}
let
elapsedTime
=
progress
*
totalDuration
/// A boolean indicating whether the transition interactive or not.
if
interactive
{
public
var
isInteractive
:
Bool
{
for
animator
in
animators
{
return
nil
==
displayLink
animator
.
seek
(
to
:
elapsedTime
)
}
}
}
else
{
/// Progress of the current transition. 0 if no transition is happening.
for
plugin
in
plugins
where
plugin
.
requirePerFrameCallback
{
public
internal(set)
var
elapsedTime
:
TimeInterval
=
0
{
plugin
.
seek
(
to
:
elapsedTime
)
didSet
{
}
guard
isTransitioning
else
{
return
}
updateTransitionObservers
()
guard
isInteractive
else
{
updatePlugins
()
return
}
updateAnimators
()
}
}
}
}
}
}
/// whether or not we are doing a transition
/// A boolean indicating whether a transition is active.
public
var
isTransitioning
:
Bool
{
public
var
isTransitioning
:
Bool
{
return
transitionContainer
!=
nil
return
nil
!=
transitionContainer
}
}
/// container we created to hold all animating views, will be a subview of the
/// transitionContainer when isTransitioning
public
internal(set)
var
container
:
UIView
!
/// this is the container supplied by UIKit
/**
internal
var
transitionContainer
:
UIView
!
A view container used to hold all the animating views during a
transition.
*/
public
internal(set)
var
container
:
UIView
!
internal
var
completionCallback
:
((
Bool
)
->
Void
)?
/// UIKit's supplied transition container.
internal
var
transitionContainer
:
UIView
!
internal
var
displayLink
:
CADisplayLink
?
/// An optional completion callback.
internal
var
progressUpdateObservers
:
[
MotionProgressUpdateObserver
]?
internal
var
completionCallback
:
((
Bool
)
->
Void
)?
/// Binds the render cycle to the transition animation.
internal
var
displayLink
:
CADisplayLink
?
/// An Array of observers that are updated during a transition.
internal
var
transitionObservers
:
[
MotionTransitionObserver
]?
/// max duration needed by the default animator and plugins
/// Max duration used by MotionAnimators and MotionPlugins.
public
internal(set)
var
totalDuration
:
TimeInterval
=
0.
0
public
internal(set)
var
totalDuration
:
TimeInterval
=
0
/// current animation complete duration.
/// The currently running animation duration.
/// (differs from totalDuration because this one could be the duration for finishing interactive transition)
internal
var
currentAnimationDuration
:
TimeInterval
=
0
internal
var
duration
:
TimeInterval
=
0.0
internal
var
beginTime
:
TimeInterval
?
{
/// The start time of the animation.
didSet
{
internal
var
beginTime
:
TimeInterval
?
{
if
beginTime
!=
nil
{
didSet
{
if
displayLink
==
nil
{
guard
nil
!=
beginTime
else
{
displayLink
=
CADisplayLink
(
target
:
self
,
selector
:
#selector(
displayUpdate(_:)
)
)
displayLink
?
.
isPaused
=
true
displayLink
!.
add
(
to
:
RunLoop
.
main
,
forMode
:
RunLoopMode
(
rawValue
:
RunLoopMode
.
commonModes
.
rawValue
))
displayLink
?
.
remove
(
from
:
RunLoop
.
main
,
forMode
:
RunLoopMode
(
rawValue
:
RunLoopMode
.
commonModes
.
rawValue
))
}
displayLink
=
nil
}
else
{
return
displayLink
?
.
isPaused
=
true
}
displayLink
?
.
remove
(
from
:
RunLoop
.
main
,
forMode
:
RunLoopMode
(
rawValue
:
RunLoopMode
.
commonModes
.
rawValue
))
displayLink
=
nil
guard
nil
==
displayLink
else
{
}
return
}
}
}
func
displayUpdate
(
_
link
:
CADisplayLink
)
{
displayLink
=
CADisplayLink
(
target
:
self
,
selector
:
#selector(
handleDisplayLink(_:)
)
)
if
isTransitioning
,
duration
>
0
,
let
beginTime
=
beginTime
{
displayLink
?
.
add
(
to
:
RunLoop
.
main
,
forMode
:
RunLoopMode
(
rawValue
:
RunLoopMode
.
commonModes
.
rawValue
))
let
elapsedTime
=
CACurrentMediaTime
()
-
beginTime
if
elapsedTime
>
duration
{
progress
=
finishing
?
1
:
0
self
.
beginTime
=
nil
complete
(
finished
:
finishing
)
}
else
{
var
completed
=
elapsedTime
/
totalDuration
if
!
finishing
{
completed
=
1
-
completed
}
}
completed
=
max
(
0
,
min
(
1
,
completed
))
progress
=
completed
}
}
}
}
internal
var
finishing
:
Bool
=
true
/// A boolean indicating if the transition has finished.
internal
var
isFinished
=
true
internal
var
processors
:
[
MotionPreprocessor
]
!
/// An Array of MotionPreprocessors used during a transition.
internal
var
animators
:
[
MotionAnimator
]
!
internal
var
processors
:
[
MotionPreprocessor
]
!
internal
var
plugins
:
[
MotionPlugin
]
!
internal
var
animatingViews
:
[(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])]
!
/// An Array of MotionAnimators used during a transition.
internal
var
animators
:
[
MotionAnimator
]
!
internal
static
var
enabledPlugins
:
[
MotionPlugin
.
Type
]
=
[]
/// An Array of MotionPlugins used during a transition.
internal
var
plugins
:
[
MotionPlugin
]
!
internal
override
init
()
{}
/// The matching from-views to to-views based on the motionIdentifier value.
internal
var
transitionPairs
:
[(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])]
!
/// Plugins that are enabled during the transition.
internal
static
var
enabledPlugins
=
[
MotionPlugin
.
Type
]()
/// Initializer.
internal
override
init
()
{}
}
fileprivate
extension
MotionController
{
/// Updates the transition observers.
func
updateTransitionObservers
()
{
guard
let
observers
=
transitionObservers
else
{
return
}
for
v
in
observers
{
v
.
motion
(
transitionObserver
:
v
,
didUpdateWith
:
elapsedTime
)
}
}
/// Updates the animators.
func
updateAnimators
()
{
let
v
=
elapsedTime
*
totalDuration
for
a
in
animators
{
a
.
seek
(
to
:
v
)
}
}
/// Updates the plugins.
func
updatePlugins
()
{
let
v
=
elapsedTime
*
totalDuration
for
p
in
plugins
where
p
.
requirePerFrameCallback
{
p
.
seek
(
to
:
v
)
}
}
}
fileprivate
extension
MotionController
{
@objc
func
handleDisplayLink
(
_
link
:
CADisplayLink
)
{
guard
isTransitioning
else
{
return
}
guard
0
<
currentAnimationDuration
else
{
return
}
guard
let
t
=
beginTime
else
{
return
}
let
cTime
=
CACurrentMediaTime
()
-
t
if
cTime
>
currentAnimationDuration
{
elapsedTime
=
isFinished
?
1
:
0
beginTime
=
nil
complete
(
isFinished
:
isFinished
)
}
else
{
var
eTime
=
cTime
/
totalDuration
if
!
isFinished
{
eTime
=
1
-
eTime
}
elapsedTime
=
max
(
0
,
min
(
1
,
eTime
))
}
}
}
}
public
extension
MotionController
{
public
extension
MotionController
{
...
@@ -140,7 +201,7 @@ public extension MotionController {
...
@@ -140,7 +201,7 @@ public extension MotionController {
public
func
update
(
progress
:
Double
)
{
public
func
update
(
progress
:
Double
)
{
guard
isTransitioning
else
{
return
}
guard
isTransitioning
else
{
return
}
self
.
beginTime
=
nil
self
.
beginTime
=
nil
self
.
progress
=
max
(
-
1
,
min
(
1
,
progress
))
self
.
elapsedTime
=
max
(
-
1
,
min
(
1
,
progress
))
}
}
/**
/**
...
@@ -151,14 +212,14 @@ public extension MotionController {
...
@@ -151,14 +212,14 @@ public extension MotionController {
public
func
end
(
animate
:
Bool
=
true
)
{
public
func
end
(
animate
:
Bool
=
true
)
{
guard
isTransitioning
else
{
return
}
guard
isTransitioning
else
{
return
}
if
!
animate
{
if
!
animate
{
self
.
complete
(
f
inished
:
true
)
self
.
complete
(
isF
inished
:
true
)
return
return
}
}
var
maxTime
:
TimeInterval
=
0
var
maxTime
:
TimeInterval
=
0
for
animator
in
self
.
animators
{
for
animator
in
self
.
animators
{
maxTime
=
max
(
maxTime
,
animator
.
resume
(
at
:
self
.
progress
*
self
.
totalDuration
,
isReversed
:
false
))
maxTime
=
max
(
maxTime
,
animator
.
resume
(
at
:
self
.
elapsedTime
*
self
.
totalDuration
,
isReversed
:
false
))
}
}
self
.
complete
(
after
:
maxTime
,
finishing
:
true
)
self
.
complete
(
after
:
maxTime
,
isFinished
:
true
)
}
}
/**
/**
...
@@ -169,18 +230,18 @@ public extension MotionController {
...
@@ -169,18 +230,18 @@ public extension MotionController {
public
func
cancel
(
animate
:
Bool
=
true
)
{
public
func
cancel
(
animate
:
Bool
=
true
)
{
guard
isTransitioning
else
{
return
}
guard
isTransitioning
else
{
return
}
if
!
animate
{
if
!
animate
{
self
.
complete
(
f
inished
:
false
)
self
.
complete
(
isF
inished
:
false
)
return
return
}
}
var
maxTime
:
TimeInterval
=
0
var
maxTime
:
TimeInterval
=
0
for
animator
in
self
.
animators
{
for
animator
in
self
.
animators
{
var
adjustedProgress
=
self
.
progress
var
adjustedProgress
=
self
.
elapsedTime
if
adjustedProgress
<
0
{
if
adjustedProgress
<
0
{
adjustedProgress
=
-
adjustedProgress
adjustedProgress
=
-
adjustedProgress
}
}
maxTime
=
max
(
maxTime
,
animator
.
resume
(
at
:
adjustedProgress
*
self
.
totalDuration
,
isReversed
:
true
))
maxTime
=
max
(
maxTime
,
animator
.
resume
(
at
:
adjustedProgress
*
self
.
totalDuration
,
isReversed
:
true
))
}
}
self
.
complete
(
after
:
maxTime
,
finishing
:
false
)
self
.
complete
(
after
:
maxTime
,
isFinished
:
false
)
}
}
/**
/**
...
@@ -219,11 +280,11 @@ public extension MotionController {
...
@@ -219,11 +280,11 @@ public extension MotionController {
- Parameters:
- Parameters:
- observer: the observer
- observer: the observer
*/
*/
func
observeForProgressUpdate
(
observer
:
Motion
ProgressUpdate
Observer
)
{
func
observeForProgressUpdate
(
observer
:
Motion
Transition
Observer
)
{
if
progressUpdate
Observers
==
nil
{
if
transition
Observers
==
nil
{
progressUpdate
Observers
=
[]
transition
Observers
=
[]
}
}
progressUpdate
Observers
!.
append
(
observer
)
transition
Observers
!.
append
(
observer
)
}
}
}
}
...
@@ -283,7 +344,7 @@ internal extension MotionController {
...
@@ -283,7 +344,7 @@ internal extension MotionController {
func
prepareForAnimation
()
{
func
prepareForAnimation
()
{
guard
isTransitioning
else
{
fatalError
()
}
guard
isTransitioning
else
{
fatalError
()
}
animatingView
s
=
[([
UIView
],
[
UIView
])]()
transitionPair
s
=
[([
UIView
],
[
UIView
])]()
for
animator
in
animators
{
for
animator
in
animators
{
let
currentFromViews
=
context
.
fromViews
.
filter
{
(
view
:
UIView
)
->
Bool
in
let
currentFromViews
=
context
.
fromViews
.
filter
{
(
view
:
UIView
)
->
Bool
in
return
animator
.
canAnimate
(
view
:
view
,
isAppearing
:
false
)
return
animator
.
canAnimate
(
view
:
view
,
isAppearing
:
false
)
...
@@ -291,7 +352,7 @@ internal extension MotionController {
...
@@ -291,7 +352,7 @@ internal extension MotionController {
let
currentToViews
=
context
.
toViews
.
filter
{
(
view
:
UIView
)
->
Bool
in
let
currentToViews
=
context
.
toViews
.
filter
{
(
view
:
UIView
)
->
Bool
in
return
animator
.
canAnimate
(
view
:
view
,
isAppearing
:
true
)
return
animator
.
canAnimate
(
view
:
view
,
isAppearing
:
true
)
}
}
animatingView
s
.
append
((
currentFromViews
,
currentToViews
))
transitionPair
s
.
append
((
currentFromViews
,
currentToViews
))
}
}
}
}
...
@@ -299,7 +360,7 @@ internal extension MotionController {
...
@@ -299,7 +360,7 @@ internal extension MotionController {
/// subclass should call `prepareForTransition` & `prepareForAnimation` before calling `animate`
/// subclass should call `prepareForTransition` & `prepareForAnimation` before calling `animate`
func
animate
()
{
func
animate
()
{
guard
isTransitioning
else
{
fatalError
()
}
guard
isTransitioning
else
{
fatalError
()
}
for
(
currentFromViews
,
currentToViews
)
in
animatingView
s
{
for
(
currentFromViews
,
currentToViews
)
in
transitionPair
s
{
// auto hide all animated views
// auto hide all animated views
for
view
in
currentFromViews
{
for
view
in
currentFromViews
{
context
.
hide
(
view
:
view
)
context
.
hide
(
view
:
view
)
...
@@ -312,8 +373,8 @@ internal extension MotionController {
...
@@ -312,8 +373,8 @@ internal extension MotionController {
var
totalDuration
:
TimeInterval
=
0
var
totalDuration
:
TimeInterval
=
0
var
animatorWantsInteractive
=
false
var
animatorWantsInteractive
=
false
for
(
i
,
animator
)
in
animators
.
enumerated
()
{
for
(
i
,
animator
)
in
animators
.
enumerated
()
{
let
duration
=
animator
.
animate
(
fromViews
:
animatingView
s
[
i
]
.
0
,
let
duration
=
animator
.
animate
(
fromViews
:
transitionPair
s
[
i
]
.
0
,
toViews
:
animatingView
s
[
i
]
.
1
)
toViews
:
transitionPair
s
[
i
]
.
1
)
if
duration
==
.
infinity
{
if
duration
==
.
infinity
{
animatorWantsInteractive
=
true
animatorWantsInteractive
=
true
}
else
{
}
else
{
...
@@ -325,23 +386,23 @@ internal extension MotionController {
...
@@ -325,23 +386,23 @@ internal extension MotionController {
if
animatorWantsInteractive
{
if
animatorWantsInteractive
{
update
(
progress
:
0
)
update
(
progress
:
0
)
}
else
{
}
else
{
complete
(
after
:
totalDuration
,
finishing
:
true
)
complete
(
after
:
totalDuration
,
isFinished
:
true
)
}
}
}
}
func
complete
(
after
:
TimeInterval
,
finishing
:
Bool
)
{
func
complete
(
after
:
TimeInterval
,
isFinished
:
Bool
)
{
guard
isTransitioning
else
{
fatalError
()
}
guard
isTransitioning
else
{
fatalError
()
}
if
after
<=
0.001
{
if
after
<=
0.001
{
complete
(
finished
:
finishing
)
complete
(
isFinished
:
isFinished
)
return
return
}
}
let
elapsedTime
=
(
finishing
?
progress
:
1
-
progress
)
*
totalDuration
let
v
=
(
isFinished
?
elapsedTime
:
1
-
elapsedTime
)
*
totalDuration
self
.
finishing
=
finishing
self
.
isFinished
=
isFinished
self
.
duration
=
after
+
elapsedTime
self
.
currentAnimationDuration
=
after
+
v
self
.
beginTime
=
CACurrentMediaTime
()
-
elapsedTime
self
.
beginTime
=
CACurrentMediaTime
()
-
v
}
}
func
complete
(
f
inished
:
Bool
)
{
func
complete
(
isF
inished
:
Bool
)
{
guard
isTransitioning
else
{
fatalError
()
}
guard
isTransitioning
else
{
fatalError
()
}
for
animator
in
animators
{
for
animator
in
animators
{
animator
.
clean
()
animator
.
clean
()
...
@@ -351,8 +412,8 @@ internal extension MotionController {
...
@@ -351,8 +412,8 @@ internal extension MotionController {
let
completion
=
completionCallback
let
completion
=
completionCallback
animatingView
s
=
nil
transitionPair
s
=
nil
progressUpdate
Observers
=
nil
transition
Observers
=
nil
transitionContainer
=
nil
transitionContainer
=
nil
completionCallback
=
nil
completionCallback
=
nil
container
=
nil
container
=
nil
...
@@ -361,10 +422,10 @@ internal extension MotionController {
...
@@ -361,10 +422,10 @@ internal extension MotionController {
plugins
=
nil
plugins
=
nil
context
=
nil
context
=
nil
beginTime
=
nil
beginTime
=
nil
progress
=
0
elapsedTime
=
0
totalDuration
=
0
totalDuration
=
0
completion
?(
f
inished
)
completion
?(
isF
inished
)
}
}
}
}
...
...
Sources/MotionTransitionObserver.swift
0 → 100644
View file @
fcf3d822
/*
* 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.
*/
import
Foundation
public
protocol
MotionTransitionObserver
{
/**
Executed when the elapsed time changes during a transition.
- Parameter transitionObserver: A MotionTransitionObserver.
- Parameter didUpdateWith elapsedTime: A TimeInterval.
*/
func
motion
(
transitionObserver
:
MotionTransitionObserver
,
didUpdateWith
elapsedTime
:
TimeInterval
)
}
Sources/Motion
Types
.swift
→
Sources/Motion
ViewController
.swift
View file @
fcf3d822
...
@@ -28,10 +28,6 @@
...
@@ -28,10 +28,6 @@
import
UIKit
import
UIKit
public
protocol
MotionProgressUpdateObserver
{
func
motionDidUpdateProgress
(
progress
:
Double
)
}
@objc(MotionViewControllerDelegate)
@objc(MotionViewControllerDelegate)
public
protocol
MotionViewControllerDelegate
{
public
protocol
MotionViewControllerDelegate
{
@objc
@objc
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment