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
19664a2f
Unverified
Commit
19664a2f
authored
Jun 07, 2017
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
partial work completed for reworking Motion and MotionController
parent
baf1bf57
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
229 additions
and
136 deletions
+229
-136
Motion.xcodeproj/project.pbxproj
+1
-1
Sources/Animator/MotionCoreAnimationViewContext.swift
+5
-0
Sources/Debug Plugin/MotionDebugPlugin.swift
+4
-4
Sources/DefaultAnimationPreprocessor.swift
+3
-3
Sources/Extensions/Motion+UIViewController.swift
+2
-1
Sources/Motion.swift
+202
-117
Sources/MotionContext.swift
+2
-2
Sources/MotionController.swift
+4
-2
Sources/MotionTargetState.swift
+6
-6
No files found.
Motion.xcodeproj/project.pbxproj
View file @
19664a2f
...
@@ -198,8 +198,8 @@
...
@@ -198,8 +198,8 @@
96AEB6691EE4610F009A3BE0
/* Debug Plugin */
,
96AEB6691EE4610F009A3BE0
/* Debug Plugin */
,
96AEB66D1EE4610F009A3BE0
/* Extensions */
,
96AEB66D1EE4610F009A3BE0
/* Extensions */
,
96AEB6771EE4610F009A3BE0
/* Motion.swift */
,
96AEB6771EE4610F009A3BE0
/* Motion.swift */
,
963150D41EE51C7A002B0D42
/* MotionAnimation.swift */
,
96AEB6781EE4610F009A3BE0
/* MotionController.swift */
,
96AEB6781EE4610F009A3BE0
/* MotionController.swift */
,
963150D41EE51C7A002B0D42
/* MotionAnimation.swift */
,
96AEB6791EE4610F009A3BE0
/* MotionContext.swift */
,
96AEB6791EE4610F009A3BE0
/* MotionContext.swift */
,
96AEB67A1EE4610F009A3BE0
/* MotionIndependentController.swift */
,
96AEB67A1EE4610F009A3BE0
/* MotionIndependentController.swift */
,
96AEB67B1EE4610F009A3BE0
/* MotionTransition.swift */
,
96AEB67B1EE4610F009A3BE0
/* MotionTransition.swift */
,
...
...
Sources/Animator/MotionCoreAnimationViewContext.swift
View file @
19664a2f
...
@@ -410,6 +410,11 @@ extension MotionCoreAnimationViewContext {
...
@@ -410,6 +410,11 @@ extension MotionCoreAnimationViewContext {
return
values
return
values
}
}
/**
Moves a layer's animation to a given elapsed time.
- Parameter layer: A CALayer.
- Parameter elapsedTime: A TimeInterval.
*/
fileprivate
func
seek
(
layer
:
CALayer
,
elapsedTime
:
TimeInterval
)
{
fileprivate
func
seek
(
layer
:
CALayer
,
elapsedTime
:
TimeInterval
)
{
let
timeOffset
=
elapsedTime
-
targetState
.
delay
let
timeOffset
=
elapsedTime
-
targetState
.
delay
for
(
key
,
anim
)
in
layer
.
animations
{
for
(
key
,
anim
)
in
layer
.
animations
{
...
...
Sources/Debug Plugin/MotionDebugPlugin.swift
View file @
19664a2f
...
@@ -38,13 +38,13 @@ public class MotionDebugPlugin: MotionPlugin {
...
@@ -38,13 +38,13 @@ public class MotionDebugPlugin: MotionPlugin {
var
updating
=
false
var
updating
=
false
override
public
func
animate
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
->
TimeInterval
{
override
public
func
animate
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
->
TimeInterval
{
if
Motion
.
shared
.
forceNo
t
Interactive
{
return
0
}
if
Motion
.
shared
.
forceNo
n
Interactive
{
return
0
}
var
hasArc
=
false
var
hasArc
=
false
for
v
in
context
.
fromViews
+
context
.
toViews
where
context
[
v
]?
.
arc
!=
nil
&&
context
[
v
]?
.
position
!=
nil
{
for
v
in
context
.
fromViews
+
context
.
toViews
where
context
[
v
]?
.
arc
!=
nil
&&
context
[
v
]?
.
position
!=
nil
{
hasArc
=
true
hasArc
=
true
break
break
}
}
let
debugView
=
MotionDebugView
(
initialProcess
:
Motion
.
shared
.
p
resenting
?
0.0
:
1.0
,
showCurveButton
:
hasArc
,
showOnTop
:
MotionDebugPlugin
.
showOnTop
)
let
debugView
=
MotionDebugView
(
initialProcess
:
Motion
.
shared
.
isP
resenting
?
0.0
:
1.0
,
showCurveButton
:
hasArc
,
showOnTop
:
MotionDebugPlugin
.
showOnTop
)
debugView
.
frame
=
Motion
.
shared
.
container
.
bounds
debugView
.
frame
=
Motion
.
shared
.
container
.
bounds
debugView
.
delegate
=
self
debugView
.
delegate
=
self
UIApplication
.
shared
.
keyWindow
!.
addSubview
(
debugView
)
UIApplication
.
shared
.
keyWindow
!.
addSubview
(
debugView
)
...
@@ -81,7 +81,7 @@ public class MotionDebugPlugin: MotionPlugin {
...
@@ -81,7 +81,7 @@ public class MotionDebugPlugin: MotionPlugin {
extension
MotionDebugPlugin
:
MotionDebugViewDelegate
{
extension
MotionDebugPlugin
:
MotionDebugViewDelegate
{
public
func
onDone
()
{
public
func
onDone
()
{
guard
let
debugView
=
debugView
else
{
return
}
guard
let
debugView
=
debugView
else
{
return
}
let
seekValue
=
Motion
.
shared
.
p
resenting
?
debugView
.
progress
:
1.0
-
debugView
.
progress
let
seekValue
=
Motion
.
shared
.
isP
resenting
?
debugView
.
progress
:
1.0
-
debugView
.
progress
if
seekValue
>
0.5
{
if
seekValue
>
0.5
{
Motion
.
shared
.
end
()
Motion
.
shared
.
end
()
}
else
{
}
else
{
...
@@ -90,7 +90,7 @@ extension MotionDebugPlugin:MotionDebugViewDelegate {
...
@@ -90,7 +90,7 @@ extension MotionDebugPlugin:MotionDebugViewDelegate {
}
}
public
func
onProcessSliderChanged
(
progress
:
Float
)
{
public
func
onProcessSliderChanged
(
progress
:
Float
)
{
let
seekValue
=
Motion
.
shared
.
p
resenting
?
progress
:
1.0
-
progress
let
seekValue
=
Motion
.
shared
.
isP
resenting
?
progress
:
1.0
-
progress
Motion
.
shared
.
update
(
progress
:
Double
(
seekValue
))
Motion
.
shared
.
update
(
progress
:
Double
(
seekValue
))
}
}
...
...
Sources/DefaultAnimationPreprocessor.swift
View file @
19664a2f
...
@@ -235,11 +235,11 @@ class DefaultAnimationPreprocessor: BasePreprocessor {
...
@@ -235,11 +235,11 @@ class DefaultAnimationPreprocessor: BasePreprocessor {
override
func
process
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
{
override
func
process
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
{
guard
let
motion
=
motion
else
{
return
}
guard
let
motion
=
motion
else
{
return
}
var
defaultAnimation
=
motion
.
defaultAnimation
var
defaultAnimation
=
motion
.
defaultAnimation
let
inNavigationController
=
motion
.
i
n
NavigationController
let
inNavigationController
=
motion
.
i
s
NavigationController
let
inTabBarController
=
motion
.
i
n
TabBarController
let
inTabBarController
=
motion
.
i
s
TabBarController
let
toViewController
=
motion
.
toViewController
let
toViewController
=
motion
.
toViewController
let
fromViewController
=
motion
.
fromViewController
let
fromViewController
=
motion
.
fromViewController
let
presenting
=
motion
.
p
resenting
let
presenting
=
motion
.
isP
resenting
let
fromOverFullScreen
=
motion
.
fromOverFullScreen
let
fromOverFullScreen
=
motion
.
fromOverFullScreen
let
toOverFullScreen
=
motion
.
toOverFullScreen
let
toOverFullScreen
=
motion
.
toOverFullScreen
let
toView
=
motion
.
toView
let
toView
=
motion
.
toView
...
...
Sources/Extensions/Motion+UIViewController.swift
View file @
19664a2f
...
@@ -312,6 +312,7 @@ extension UIViewController {
...
@@ -312,6 +312,7 @@ extension UIViewController {
/**
/**
Replace the current view controller with another view controller on the
Replace the current view controller with another view controller on the
navigation/modal stack.
navigation/modal stack.
- Parameter with next: A UIViewController.
*/
*/
public
func
motion_replaceViewController
(
with
next
:
UIViewController
)
{
public
func
motion_replaceViewController
(
with
next
:
UIViewController
)
{
guard
!
Motion
.
shared
.
isTransitioning
else
{
guard
!
Motion
.
shared
.
isTransitioning
else
{
...
@@ -328,7 +329,7 @@ extension UIViewController {
...
@@ -328,7 +329,7 @@ extension UIViewController {
}
}
if
navigationController
.
isMotionEnabled
{
if
navigationController
.
isMotionEnabled
{
Motion
.
shared
.
forceNo
t
Interactive
=
true
Motion
.
shared
.
forceNo
n
Interactive
=
true
}
}
navigationController
.
setViewControllers
(
v
,
animated
:
true
)
navigationController
.
setViewControllers
(
v
,
animated
:
true
)
...
...
Sources/Motion.swift
View file @
19664a2f
...
@@ -41,25 +41,23 @@ import UIKit
...
@@ -41,25 +41,23 @@ import UIKit
func update(progress:Double)
func update(progress:Double)
func end()
func end()
func cancel()
func cancel()
func apply(
modifiers:[MotionTransition], to view:
UIView)
func apply(
transitions: [MotionTransition], to view:
UIView)
```
```
*/
*/
public
class
Motion
:
MotionController
{
public
class
Motion
:
MotionController
{
// MARK: Shared Access
/// Shared singleton object for controlling the transition
/// Shared singleton object for controlling the transition
public
static
let
shared
=
Motion
()
public
static
let
shared
=
Motion
()
// MARK: Properties
/// Source view controller.
public
internal(set)
var
fromViewController
:
UIViewController
?
/// destination view controller
/// Destination view controller.
public
internal(set)
var
toViewController
:
UIViewController
?
public
internal(set)
var
toViewController
:
UIViewController
?
/// source view controller
public
internal(set)
var
fromViewController
:
UIViewController
?
/// whether or not we are presenting the destination view controller
public
internal(set)
var
presenting
=
true
/// progress of the current transition. 0 if no transition is happening
/// Whether or not we are presenting the destination view controller.
public
internal(set)
var
isPresenting
=
true
/// Progress of the current transition, 0 if a transition is not happening.
public
override
var
progress
:
Double
{
public
override
var
progress
:
Double
{
didSet
{
didSet
{
if
isTransitioning
{
if
isTransitioning
{
...
@@ -68,107 +66,108 @@ public class Motion: MotionController {
...
@@ -68,107 +66,108 @@ public class Motion: MotionController {
}
}
}
}
public
var
isAnimating
:
Bool
=
false
/// Indicates whether the transition is animating or not.
/// a UIViewControllerContextTransitioning object provided by UIKit,
public
var
isAnimating
=
false
/// might be nil when isTransitioning. This happens when calling motionReplaceViewController
/**
A UIViewControllerContextTransitioning object provided by UIKit, which
might be nil when isTransitioning. This happens when calling motion_replaceViewController
*/
internal
weak
var
transitionContext
:
UIViewControllerContextTransitioning
?
internal
weak
var
transitionContext
:
UIViewControllerContextTransitioning
?
/// A reference to a fullscreen snapshot.
internal
var
fullScreenSnapshot
:
UIView
!
internal
var
fullScreenSnapshot
:
UIView
!
internal
var
defaultAnimation
:
MotionDefaultAnimationType
=
.
auto
/// Default animation type.
internal
var
containerColor
:
UIColor
?
internal
var
defaultAnimation
=
MotionDefaultAnimationType
.
auto
// By default, Motion will always appear to be interactive to UIKit. This forces it to appear non-interactive.
/// The color of the transitioning container.
// Used when doing a motion_replaceViewController within a UINavigationController, to fix a bug with
internal
var
containerBackgroundColor
:
UIColor
?
// UINavigationController.setViewControllers not able to handle interactive transition
internal
var
forceNotInteractive
=
false
/**
By default, Motion will always appear to be interactive to UIKit. This forces it to appear non-interactive.
Used when doing a motion_replaceViewController within a UINavigationController, to fix a bug with
UINavigationController.setViewControllers not able to handle interactive transitions.
*/
internal
var
forceNonInteractive
=
false
/// Inserts the to-views first.
internal
var
insertToViewFirst
=
false
internal
var
insertToViewFirst
=
false
internal
var
inNavigationController
=
false
/// Indicates whether a UINavigationController is transitioning.
internal
var
inTabBarController
=
false
internal
var
isNavigationController
=
false
internal
var
inContainerController
:
Bool
{
return
inNavigationController
||
inTabBarController
/// Indicates whether a UITabBarController is transitioning.
internal
var
isTabBarController
=
false
/// Indicates whether a UINavigationController or UITabBarController is transitioning.
internal
var
isContainerController
:
Bool
{
return
isNavigationController
||
isTabBarController
}
/// Indicates whether the from view controller is full screen.
internal
var
fromOverFullScreen
:
Bool
{
return
!
isContainerController
&&
(
.
overFullScreen
==
fromViewController
!.
modalPresentationStyle
||
.
overCurrentContext
==
fromViewController
!.
modalPresentationStyle
)
}
}
/// Indicates whether the to view controller is full screen.
internal
var
toOverFullScreen
:
Bool
{
internal
var
toOverFullScreen
:
Bool
{
return
!
inContainerController
&&
(
toViewController
!.
modalPresentationStyle
==
.
overFullScreen
||
toViewController
!.
modalPresentationStyle
==
.
overCurrentContext
)
return
!
isContainerController
&&
(
.
overFullScreen
==
toViewController
!.
modalPresentationStyle
||
.
overCurrentContext
==
toViewController
!.
modalPresentationStyle
)
}
}
internal
var
fromOverFullScreen
:
Bool
{
return
!
inContainerController
&&
(
fromViewController
!.
modalPresentationStyle
==
.
overFullScreen
||
fromViewController
!.
modalPresentationStyle
==
.
overCurrentContext
)
/// A reference to the from-view, fromViewController.view.
internal
var
fromView
:
UIView
{
return
fromViewController
!.
view
}
}
internal
var
toView
:
UIView
{
return
toViewController
!.
view
}
/// A reference to the to-view, toViewController.view.
internal
var
fromView
:
UIView
{
return
fromViewController
!.
view
}
internal
var
toView
:
UIView
{
return
toViewController
!.
view
}
internal
override
init
()
{
super
.
init
()
}
/// An initializer.
internal
override
init
()
{
super
.
init
()
}
}
}
public
extension
Motion
{
public
extension
Motion
{
/// Turn off built-in animations for the next transition.
/// Turn off built-in animation for next transition
func
disableDefaultAnimationForNextTransition
()
{
func
disableDefaultAnimationForNextTransition
()
{
defaultAnimation
=
.
none
defaultAnimation
=
.
none
}
}
/// Set the default animation for next transition
/**
/// This usually overrides rootView's motionTransitions during the transition
Set the default animation for the next transition. This may override the
///
root-view's motionTransitions during the transition.
/// - Parameter animation: animation type
- Parameter animation: A MotionDefaultAnimationType.
*/
func
setDefaultAnimationForNextTransition
(
_
animation
:
MotionDefaultAnimationType
)
{
func
setDefaultAnimationForNextTransition
(
_
animation
:
MotionDefaultAnimationType
)
{
defaultAnimation
=
animation
defaultAnimation
=
animation
}
}
/// Set the container color for next transition
/**
///
Set the container background color for the next transition.
/// - Parameter color: container color
- Parameter _ color: An optional UIColor.
func
setContainerColorForNextTransition
(
_
color
:
UIColor
?)
{
*/
containerColor
=
color
func
setContainerBackgroundColorForNextTransition
(
_
color
:
UIColor
?)
{
containerBackgroundColor
=
color
}
}
}
}
// internal methods for transition
internal
extension
Motion
{
internal
extension
Motion
{
/// Starts the transition animation.
func
start
()
{
func
start
()
{
guard
isTransitioning
else
{
return
}
guard
isTransitioning
else
{
if
let
fvc
=
fromViewController
,
let
tvc
=
toViewController
{
return
closureProcessForMotionDelegate
(
vc
:
fvc
)
{
$0
.
motionWillStartTransition
?()
$0
.
motionWillStartAnimatingTo
?(
viewController
:
tvc
)
}
closureProcessForMotionDelegate
(
vc
:
tvc
)
{
$0
.
motionWillStartTransition
?()
$0
.
motionWillStartAnimatingFrom
?(
viewController
:
fvc
)
}
}
// take a snapshot to hide all the flashing that might happen
fullScreenSnapshot
=
transitionContainer
.
window
?
.
snapshotView
(
afterScreenUpdates
:
true
)
??
fromView
.
snapshotView
(
afterScreenUpdates
:
true
)
(
transitionContainer
.
window
??
transitionContainer
)?
.
addSubview
(
fullScreenSnapshot
)
if
let
oldSnapshot
=
fromViewController
?
.
motionStoredSnapshot
{
oldSnapshot
.
removeFromSuperview
()
fromViewController
?
.
motionStoredSnapshot
=
nil
}
if
let
oldSnapshot
=
toViewController
?
.
motionStoredSnapshot
{
oldSnapshot
.
removeFromSuperview
()
toViewController
?
.
motionStoredSnapshot
=
nil
}
}
prepareViewControllers
()
prepareSnapshotView
()
prepareForTransition
()
prepareForTransition
()
insert
(
preprocessor
:
DefaultAnimationPreprocessor
(
motion
:
self
),
before
:
DurationPreprocessor
.
self
)
prepareMotionContext
()
prepareToView
()
context
.
loadViewAlpha
(
rootView
:
toView
)
prepareViewHierarchy
()
context
.
loadViewAlpha
(
rootView
:
fromView
)
container
.
addSubview
(
toView
)
container
.
addSubview
(
fromView
)
toView
.
frame
=
fromView
.
frame
toView
.
updateConstraints
()
toView
.
setNeedsLayout
()
toView
.
layoutIfNeeded
()
context
.
set
(
fromViews
:
fromView
.
flattenedViewHierarchy
,
toViews
:
toView
.
flattenedViewHierarchy
)
processContext
()
processContext
()
prepareForAnimation
()
prepareForAnimation
()
...
@@ -178,11 +177,11 @@ internal extension Motion {
...
@@ -178,11 +177,11 @@ internal extension Motion {
#if os(tvOS)
#if os(tvOS)
animate
()
animate
()
#else
#else
if
in
NavigationController
{
if
is
NavigationController
{
// When animating within navigationController, we have to dispatch later into the main queue.
// When animating within navigationController, we have to dispatch later into the main queue.
// otherwise snapshots will be pure white. Possibly a bug with UIKit
// otherwise snapshots will be pure white. Possibly a bug with UIKit
DispatchQueue
.
main
.
async
{
DispatchQueue
.
main
.
async
{
[
weak
self
]
in
self
.
animate
()
self
?
.
animate
()
}
}
}
else
{
}
else
{
animate
()
animate
()
...
@@ -193,8 +192,8 @@ internal extension Motion {
...
@@ -193,8 +192,8 @@ internal extension Motion {
override
func
animate
()
{
override
func
animate
()
{
context
.
unhide
(
view
:
toView
)
context
.
unhide
(
view
:
toView
)
if
let
containerColor
=
container
Color
{
if
let
containerBackgroundColor
=
containerBackground
Color
{
container
.
backgroundColor
=
container
Color
container
.
backgroundColor
=
containerBackground
Color
}
else
if
!
toOverFullScreen
&&
!
fromOverFullScreen
{
}
else
if
!
toOverFullScreen
&&
!
fromOverFullScreen
{
container
.
backgroundColor
=
toView
.
backgroundColor
container
.
backgroundColor
=
toView
.
backgroundColor
}
}
...
@@ -202,6 +201,7 @@ internal extension Motion {
...
@@ -202,6 +201,7 @@ internal extension Motion {
if
fromOverFullScreen
{
if
fromOverFullScreen
{
insertToViewFirst
=
true
insertToViewFirst
=
true
}
}
for
animator
in
animators
{
for
animator
in
animators
{
if
let
animator
=
animator
as?
MotionHasInsertOrder
{
if
let
animator
=
animator
as?
MotionHasInsertOrder
{
animator
.
insertToViewFirst
=
insertToViewFirst
animator
.
insertToViewFirst
=
insertToViewFirst
...
@@ -209,27 +209,31 @@ internal extension Motion {
...
@@ -209,27 +209,31 @@ internal extension Motion {
}
}
super
.
animate
()
super
.
animate
()
fullScreenSnapshot
!.
removeFromSuperview
()
fullScreenSnapshot
!.
removeFromSuperview
()
}
}
override
func
complete
(
finished
:
Bool
)
{
override
func
complete
(
finished
:
Bool
)
{
guard
isTransitioning
else
{
return
}
guard
isTransitioning
else
{
return
}
context
.
clean
()
context
.
clean
()
if
finished
&&
presenting
&&
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
)
}
else
if
!
finished
&&
!
p
resenting
&&
fromOverFullScreen
{
}
else
if
!
finished
&&
!
isP
resenting
&&
fromOverFullScreen
{
// cancelled dismissing a overFullScreen VC
// cancelled dismissing a overFullScreen VC
context
.
unhide
(
rootView
:
fromView
)
context
.
unhide
(
rootView
:
fromView
)
context
.
removeSnapshots
(
rootView
:
fromView
)
context
.
removeSnapshots
(
rootView
:
fromView
)
context
.
storeViewAlpha
(
rootView
:
toView
)
context
.
storeViewAlpha
(
rootView
:
toView
)
toViewController
!.
motionStoredSnapshot
=
container
toViewController
!.
motionStoredSnapshot
=
container
toView
.
removeFromSuperview
()
toView
.
removeFromSuperview
()
toView
.
addSubview
(
container
)
toView
.
addSubview
(
container
)
...
@@ -243,12 +247,13 @@ internal extension Motion {
...
@@ -243,12 +247,13 @@ internal extension Motion {
if
(
toOverFullScreen
&&
finished
)
||
(
fromOverFullScreen
&&
!
finished
)
{
if
(
toOverFullScreen
&&
finished
)
||
(
fromOverFullScreen
&&
!
finished
)
{
transitionContainer
.
addSubview
(
finished
?
fromView
:
toView
)
transitionContainer
.
addSubview
(
finished
?
fromView
:
toView
)
}
}
transitionContainer
.
addSubview
(
finished
?
toView
:
fromView
)
transitionContainer
.
addSubview
(
finished
?
toView
:
fromView
)
if
presenting
!=
finished
,
!
in
ContainerController
{
if
isPresenting
!=
finished
,
!
is
ContainerController
{
// only happens when present a .overFullScreen VC
// only happens when present a .overFullScreen VC
// bug: http://openradar.appspot.com/radar?id=5320103646199808
// bug: http://openradar.appspot.com/radar?id=5320103646199808
UIApplication
.
shared
.
keyWindow
!.
addSubview
(
p
resenting
?
fromView
:
toView
)
UIApplication
.
shared
.
keyWindow
!.
addSubview
(
isP
resenting
?
fromView
:
toView
)
}
}
// use temp variables to remember these values
// use temp variables to remember these values
...
@@ -261,10 +266,10 @@ internal extension Motion {
...
@@ -261,10 +266,10 @@ internal extension Motion {
transitionContext
=
nil
transitionContext
=
nil
fromViewController
=
nil
fromViewController
=
nil
toViewController
=
nil
toViewController
=
nil
container
Color
=
nil
containerBackground
Color
=
nil
in
NavigationController
=
false
is
NavigationController
=
false
in
TabBarController
=
false
is
TabBarController
=
false
forceNot
Interactive
=
false
forceNon
Interactive
=
false
insertToViewFirst
=
false
insertToViewFirst
=
false
defaultAnimation
=
.
auto
defaultAnimation
=
.
auto
...
@@ -272,63 +277,143 @@ internal extension Motion {
...
@@ -272,63 +277,143 @@ internal extension Motion {
if
finished
{
if
finished
{
if
let
fvc
=
fvc
,
let
tvc
=
tvc
{
if
let
fvc
=
fvc
,
let
tvc
=
tvc
{
closureProcessForMotionDelegate
(
vc
:
fvc
)
{
processForMotionDelegate
(
viewController
:
fvc
)
{
$0
.
motionDidEndAnimatingTo
?(
viewController
:
tvc
)
$0
.
motionDidEndAnimatingTo
?(
viewController
:
tvc
)
$0
.
motionDidEndTransition
?()
$0
.
motionDidEndTransition
?()
}
}
closureProcessForMotionDelegate
(
vc
:
tvc
)
{
processForMotionDelegate
(
viewController
:
tvc
)
{
$0
.
motionDidEndAnimatingFrom
?(
viewController
:
fvc
)
$0
.
motionDidEndAnimatingFrom
?(
viewController
:
fvc
)
$0
.
motionDidEndTransition
?()
$0
.
motionDidEndTransition
?()
}
}
}
}
tContext
?
.
finishInteractiveTransition
()
tContext
?
.
finishInteractiveTransition
()
}
else
{
}
else
{
if
let
fvc
=
fvc
,
let
tvc
=
tvc
{
if
let
fvc
=
fvc
,
let
tvc
=
tvc
{
closureProcessForMotionDelegate
(
vc
:
fvc
)
{
processForMotionDelegate
(
viewController
:
fvc
)
{
$0
.
motionDidCancelAnimatingTo
?(
viewController
:
tvc
)
$0
.
motionDidCancelAnimatingTo
?(
viewController
:
tvc
)
$0
.
motionDidCancelTransition
?()
$0
.
motionDidCancelTransition
?()
}
}
closureProcessForMotionDelegate
(
vc
:
tvc
)
{
processForMotionDelegate
(
viewController
:
tvc
)
{
$0
.
motionDidCancelAnimatingFrom
?(
viewController
:
fvc
)
$0
.
motionDidCancelAnimatingFrom
?(
viewController
:
fvc
)
$0
.
motionDidCancelTransition
?()
$0
.
motionDidCancelTransition
?()
}
}
}
}
tContext
?
.
cancelInteractiveTransition
()
tContext
?
.
cancelInteractiveTransition
()
}
}
tContext
?
.
completeTransition
(
finished
)
tContext
?
.
completeTransition
(
finished
)
}
}
}
}
// custom transition helper, used in motion_replaceViewController
fileprivate
extension
Motion
{
/// Prepares the from and to view controllers.
func
prepareViewControllers
()
{
guard
let
fvc
=
fromViewController
,
let
tvc
=
toViewController
else
{
return
}
processForMotionDelegate
(
viewController
:
fvc
)
{
$0
.
motionWillStartTransition
?()
$0
.
motionWillStartAnimatingTo
?(
viewController
:
tvc
)
}
processForMotionDelegate
(
viewController
:
tvc
)
{
$0
.
motionWillStartTransition
?()
$0
.
motionWillStartAnimatingFrom
?(
viewController
:
fvc
)
}
}
/// Prepares the snapshot view, which hides any flashing that may occur.
func
prepareSnapshotView
()
{
fullScreenSnapshot
=
transitionContainer
.
window
?
.
snapshotView
(
afterScreenUpdates
:
true
)
??
fromView
.
snapshotView
(
afterScreenUpdates
:
true
)
(
transitionContainer
.
window
??
transitionContainer
)?
.
addSubview
(
fullScreenSnapshot
)
if
let
v
=
fromViewController
?
.
motionStoredSnapshot
{
v
.
removeFromSuperview
()
fromViewController
?
.
motionStoredSnapshot
=
nil
}
if
let
v
=
toViewController
?
.
motionStoredSnapshot
{
v
.
removeFromSuperview
()
toViewController
?
.
motionStoredSnapshot
=
nil
}
}
/// Prepares the MotionContext instance.
func
prepareMotionContext
()
{
context
.
loadViewAlpha
(
rootView
:
toView
)
context
.
loadViewAlpha
(
rootView
:
fromView
)
container
.
addSubview
(
toView
)
container
.
addSubview
(
fromView
)
}
/// Prepares the toView instance.
func
prepareToView
()
{
toView
.
frame
=
fromView
.
frame
toView
.
updateConstraints
()
toView
.
setNeedsLayout
()
toView
.
layoutIfNeeded
()
}
/// Prepares the view hierarchy.
func
prepareViewHierarchy
()
{
context
.
set
(
fromViews
:
fromView
.
flattenedViewHierarchy
,
toViews
:
toView
.
flattenedViewHierarchy
)
}
}
internal
extension
Motion
{
internal
extension
Motion
{
override
func
prepareForTransition
()
{
super
.
prepareForTransition
()
insert
(
preprocessor
:
DefaultAnimationPreprocessor
(
motion
:
self
),
before
:
DurationPreprocessor
.
self
)
}
}
internal
extension
Motion
{
/**
A helper transition function.
- Parameter from: A UIViewController.
- Parameter to: A UIViewController.
- Parameter in view: A UIView.
- Parameter completion: An optional completion handler.
*/
func
transition
(
from
:
UIViewController
,
to
:
UIViewController
,
in
view
:
UIView
,
completion
:
((
Bool
)
->
Void
)?
=
nil
)
{
func
transition
(
from
:
UIViewController
,
to
:
UIViewController
,
in
view
:
UIView
,
completion
:
((
Bool
)
->
Void
)?
=
nil
)
{
guard
!
isTransitioning
else
{
return
}
guard
!
isTransitioning
else
{
presenting
=
true
return
}
isPresenting
=
true
transitionContainer
=
view
transitionContainer
=
view
fromViewController
=
from
fromViewController
=
from
toViewController
=
to
toViewController
=
to
completionCallback
=
completion
completionCallback
=
completion
start
()
start
()
}
}
}
}
// delegate helper
internal
extension
Motion
{
internal
extension
Motion
{
func
closureProcessForMotionDelegate
<
T
:
UIViewController
>
(
vc
:
T
,
closure
:
(
MotionViewControllerDelegate
)
->
Void
)
{
/**
if
let
delegate
=
vc
as?
MotionViewControllerDelegate
{
Helper for processing the MotionViewControllerDelegate.
closure
(
delegate
)
- Parameter viewController: A UIViewController of type `T`.
- Parameter execute: A callback for execution during processing.
*/
func
processForMotionDelegate
<
T
:
UIViewController
>
(
viewController
:
T
,
execute
:
(
MotionViewControllerDelegate
)
->
Void
)
{
if
let
delegate
=
viewController
as?
MotionViewControllerDelegate
{
execute
(
delegate
)
}
}
if
let
navigationController
=
vc
as?
UINavigationController
,
if
let
v
=
viewController
as?
UINavigationController
,
let
delegate
=
navigationController
.
topViewController
as?
MotionViewControllerDelegate
{
let
delegate
=
v
.
topViewController
as?
MotionViewControllerDelegate
{
closur
e
(
delegate
)
execut
e
(
delegate
)
}
}
if
let
tabBarController
=
vc
as?
UITabBarController
,
if
let
v
=
viewController
as?
UITabBarController
,
let
delegate
=
tabBarController
.
viewControllers
?[
tabBarController
.
selectedIndex
]
as?
MotionViewControllerDelegate
{
let
delegate
=
v
.
viewControllers
?[
v
.
selectedIndex
]
as?
MotionViewControllerDelegate
{
closur
e
(
delegate
)
execut
e
(
delegate
)
}
}
}
}
}
}
...
@@ -359,18 +444,18 @@ extension Motion: UIViewControllerAnimatedTransitioning {
...
@@ -359,18 +444,18 @@ extension Motion: UIViewControllerAnimatedTransitioning {
extension
Motion
:
UIViewControllerTransitioningDelegate
{
extension
Motion
:
UIViewControllerTransitioningDelegate
{
var
interactiveTransitioning
:
UIViewControllerInteractiveTransitioning
?
{
var
interactiveTransitioning
:
UIViewControllerInteractiveTransitioning
?
{
return
forceNo
t
Interactive
?
nil
:
self
return
forceNo
n
Interactive
?
nil
:
self
}
}
public
func
animationController
(
forPresented
presented
:
UIViewController
,
presenting
:
UIViewController
,
source
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
public
func
animationController
(
forPresented
presented
:
UIViewController
,
presenting
:
UIViewController
,
source
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
self
.
p
resenting
=
true
self
.
isP
resenting
=
true
self
.
fromViewController
=
fromViewController
??
presenting
self
.
fromViewController
=
fromViewController
??
presenting
self
.
toViewController
=
toViewController
??
presented
self
.
toViewController
=
toViewController
??
presented
return
self
return
self
}
}
public
func
animationController
(
forDismissed
dismissed
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
public
func
animationController
(
forDismissed
dismissed
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
self
.
p
resenting
=
false
self
.
isP
resenting
=
false
self
.
fromViewController
=
fromViewController
??
dismissed
self
.
fromViewController
=
fromViewController
??
dismissed
return
self
return
self
}
}
...
@@ -395,10 +480,10 @@ extension Motion: UIViewControllerInteractiveTransitioning {
...
@@ -395,10 +480,10 @@ extension Motion: UIViewControllerInteractiveTransitioning {
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
.
p
resenting
=
operation
==
.
push
self
.
isP
resenting
=
operation
==
.
push
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
toViewController
=
toViewController
??
toVC
self
.
toViewController
=
toViewController
??
toVC
self
.
i
n
NavigationController
=
true
self
.
i
s
NavigationController
=
true
return
self
return
self
}
}
...
@@ -420,10 +505,10 @@ extension Motion: UITabBarControllerDelegate {
...
@@ -420,10 +505,10 @@ extension Motion: UITabBarControllerDelegate {
isAnimating
=
true
isAnimating
=
true
let
fromVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
fromVC
)
!
let
fromVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
fromVC
)
!
let
toVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
toVC
)
!
let
toVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
toVC
)
!
self
.
p
resenting
=
toVCIndex
>
fromVCIndex
self
.
isP
resenting
=
toVCIndex
>
fromVCIndex
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
toViewController
=
toViewController
??
toVC
self
.
toViewController
=
toViewController
??
toVC
self
.
i
n
TabBarController
=
true
self
.
i
s
TabBarController
=
true
return
self
return
self
}
}
}
}
...
...
Sources/MotionContext.swift
View file @
19664a2f
...
@@ -56,8 +56,8 @@ public class MotionContext {
...
@@ -56,8 +56,8 @@ public class MotionContext {
if
let
motionIdentifier
=
view
.
motionIdentifier
{
if
let
motionIdentifier
=
view
.
motionIdentifier
{
idMap
[
motionIdentifier
]
=
view
idMap
[
motionIdentifier
]
=
view
}
}
if
let
modifier
s
=
view
.
motionTransitions
{
if
let
transition
s
=
view
.
motionTransitions
{
targetStates
[
view
]
=
MotionTargetState
(
modifiers
:
modifier
s
)
targetStates
[
view
]
=
MotionTargetState
(
transitions
:
transition
s
)
}
}
}
}
}
}
...
...
Sources/MotionController.swift
View file @
19664a2f
...
@@ -195,9 +195,9 @@ public extension MotionController {
...
@@ -195,9 +195,9 @@ public extension MotionController {
- modifiers: the modifiers to override
- modifiers: the modifiers to override
- view: the view to override to
- view: the view to override to
*/
*/
public
func
apply
(
modifier
s
:
[
MotionTransition
],
to
view
:
UIView
)
{
public
func
apply
(
transition
s
:
[
MotionTransition
],
to
view
:
UIView
)
{
guard
isTransitioning
else
{
return
}
guard
isTransitioning
else
{
return
}
let
targetState
=
MotionTargetState
(
modifiers
:
modifier
s
)
let
targetState
=
MotionTargetState
(
transitions
:
transition
s
)
if
let
otherView
=
self
.
context
.
pairedView
(
for
:
view
)
{
if
let
otherView
=
self
.
context
.
pairedView
(
for
:
view
)
{
for
animator
in
self
.
animators
{
for
animator
in
self
.
animators
{
animator
.
apply
(
state
:
targetState
,
to
:
otherView
)
animator
.
apply
(
state
:
targetState
,
to
:
otherView
)
...
@@ -272,6 +272,8 @@ internal extension MotionController {
...
@@ -272,6 +272,8 @@ internal extension MotionController {
}
}
}
}
func
processContext
()
{
func
processContext
()
{
guard
isTransitioning
else
{
fatalError
()
}
guard
isTransitioning
else
{
fatalError
()
}
for
processor
in
processors
{
for
processor
in
processors
{
...
...
Sources/MotionTargetState.swift
View file @
19664a2f
...
@@ -105,16 +105,16 @@ public struct MotionTargetState {
...
@@ -105,16 +105,16 @@ public struct MotionTargetState {
public
var
forceAnimate
:
Bool
=
false
public
var
forceAnimate
:
Bool
=
false
public
var
custom
:
[
String
:
Any
]?
public
var
custom
:
[
String
:
Any
]?
init
(
modifier
s
:
[
MotionTransition
])
{
init
(
transition
s
:
[
MotionTransition
])
{
append
(
contentsOf
:
modifier
s
)
append
(
contentsOf
:
transition
s
)
}
}
public
mutating
func
append
(
_
modifier
:
MotionTransition
)
{
public
mutating
func
append
(
_
transition
:
MotionTransition
)
{
modifier
.
apply
(
&
self
)
transition
.
apply
(
&
self
)
}
}
public
mutating
func
append
(
contentsOf
modifier
s
:
[
MotionTransition
])
{
public
mutating
func
append
(
contentsOf
transition
s
:
[
MotionTransition
])
{
for
modifier
in
modifier
s
{
for
modifier
in
transition
s
{
modifier
.
apply
(
&
self
)
modifier
.
apply
(
&
self
)
}
}
}
}
...
...
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