Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
Material
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
Material
Commits
1e63fdbd
Unverified
Commit
1e63fdbd
authored
Jan 22, 2017
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
development: added transitionView to MotionTransition animations
parent
e46c5a84
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
270 additions
and
288 deletions
+270
-288
Sources/iOS/Material+UIView.swift
+33
-0
Sources/iOS/MotionAnimation.swift
+46
-6
Sources/iOS/MotionTransition.swift
+191
-282
No files found.
Sources/iOS/Material+UIView.swift
View file @
1e63fdbd
...
@@ -32,6 +32,39 @@ import UIKit
...
@@ -32,6 +32,39 @@ import UIKit
/// Grid extension for UIView.
/// Grid extension for UIView.
extension
UIView
{
extension
UIView
{
/// A property that accesses the backing layer's masksToBounds.
@IBInspectable
open
var
masksToBounds
:
Bool
{
get
{
return
layer
.
masksToBounds
}
set
(
value
)
{
layer
.
masksToBounds
=
value
}
}
/// A property that accesses the backing layer's opacity.
@IBInspectable
open
var
opacity
:
Float
{
get
{
return
layer
.
opacity
}
set
(
value
)
{
layer
.
opacity
=
value
}
}
/// A property that accesses the backing layer's anchorPoint.
@IBInspectable
open
var
anchorPoint
:
CGPoint
{
get
{
return
layer
.
anchorPoint
}
set
(
value
)
{
layer
.
anchorPoint
=
value
}
}
/// A property that accesses the frame.origin.x property.
/// A property that accesses the frame.origin.x property.
@IBInspectable
@IBInspectable
open
var
x
:
CGFloat
{
open
var
x
:
CGFloat
{
...
...
Sources/iOS/MotionAnimation.swift
View file @
1e63fdbd
...
@@ -52,6 +52,7 @@ public enum MotionAnimationKeyPath: String {
...
@@ -52,6 +52,7 @@ public enum MotionAnimationKeyPath: String {
case
zPosition
case
zPosition
case
width
=
"bounds.size.width"
case
width
=
"bounds.size.width"
case
height
=
"bounds.size.height"
case
height
=
"bounds.size.height"
case
size
=
"bounds.size"
}
}
public
enum
MotionAnimation
{
public
enum
MotionAnimation
{
...
@@ -87,6 +88,7 @@ public enum MotionAnimation {
...
@@ -87,6 +88,7 @@ public enum MotionAnimation {
case
zPosition
(
Int
)
case
zPosition
(
Int
)
case
width
(
CGFloat
)
case
width
(
CGFloat
)
case
height
(
CGFloat
)
case
height
(
CGFloat
)
case
size
(
CGSize
)
}
}
extension
CALayer
{
extension
CALayer
{
...
@@ -190,6 +192,22 @@ extension CALayer {
...
@@ -190,6 +192,22 @@ extension CALayer {
var
tf
=
timingFunction
var
tf
=
timingFunction
var
d
=
duration
var
d
=
duration
var
px
:
CGFloat
=
s
.
position
.
x
var
py
:
CGFloat
=
s
.
position
.
y
for
v
in
animations
{
switch
v
{
case
let
.
x
(
x
):
px
=
x
+
w
/
2
case
let
.
y
(
y
):
py
=
y
+
h
/
2
case
let
.
point
(
x
,
y
):
px
=
x
+
w
/
2
py
=
y
+
h
/
2
default
:
break
}
}
for
v
in
animations
{
for
v
in
animations
{
switch
v
{
switch
v
{
case
let
.
timingFunction
(
timingFunction
):
case
let
.
timingFunction
(
timingFunction
):
...
@@ -239,12 +257,9 @@ extension CALayer {
...
@@ -239,12 +257,9 @@ extension CALayer {
a
.
append
(
Motion
.
translateY
(
to
:
to
))
a
.
append
(
Motion
.
translateY
(
to
:
to
))
case
let
.
translateZ
(
to
):
case
let
.
translateZ
(
to
):
a
.
append
(
Motion
.
translateZ
(
to
:
to
))
a
.
append
(
Motion
.
translateZ
(
to
:
to
))
case
let
.
x
(
x
):
case
let
.
x
(
_
),
.
y
(
_
),
.
point
(
_
,
_
):
a
.
append
(
Motion
.
position
(
to
:
CGPoint
(
x
:
x
+
w
/
2
,
y
:
s
.
position
.
y
)))
let
position
=
Motion
.
position
(
to
:
CGPoint
(
x
:
px
,
y
:
py
))
case
let
.
y
(
y
):
a
.
append
(
position
)
a
.
append
(
Motion
.
position
(
to
:
CGPoint
(
x
:
s
.
position
.
x
,
y
:
y
+
h
/
2
)))
case
let
.
point
(
x
,
y
):
a
.
append
(
Motion
.
position
(
to
:
CGPoint
(
x
:
x
+
w
/
2
,
y
:
y
+
h
/
2
)))
case
let
.
position
(
x
,
y
):
case
let
.
position
(
x
,
y
):
a
.
append
(
Motion
.
position
(
to
:
CGPoint
(
x
:
x
,
y
:
y
)))
a
.
append
(
Motion
.
position
(
to
:
CGPoint
(
x
:
x
,
y
:
y
)))
case
let
.
shadow
(
path
):
case
let
.
shadow
(
path
):
...
@@ -261,6 +276,8 @@ extension CALayer {
...
@@ -261,6 +276,8 @@ extension CALayer {
a
.
append
(
Motion
.
width
(
w
))
a
.
append
(
Motion
.
width
(
w
))
case
let
.
height
(
h
):
case
let
.
height
(
h
):
a
.
append
(
Motion
.
height
(
h
))
a
.
append
(
Motion
.
height
(
h
))
case
let
.
size
(
size
):
a
.
append
(
Motion
.
size
(
size
))
default
:
break
default
:
break
}
}
}
}
...
@@ -523,6 +540,18 @@ extension Motion {
...
@@ -523,6 +540,18 @@ extension Motion {
/**
/**
Creates a CABasicAnimation for the position key path.
Creates a CABasicAnimation for the position key path.
- Parameter x: A CGFloat.
- Parameter y: A CGFloat.
- Returns: A CABasicAnimation.
*/
public
static
func
position
(
x
:
CGFloat
,
y
:
CGFloat
)
->
CABasicAnimation
{
let
animation
=
CABasicAnimation
(
keyPath
:
.
position
)
animation
.
toValue
=
NSValue
(
cgPoint
:
CGPoint
(
x
:
x
,
y
:
y
))
return
animation
}
/**
Creates a CABasicAnimation for the position key path.
- Parameter to point: A CGPoint.
- Parameter to point: A CGPoint.
- Returns: A CABasicAnimation.
- Returns: A CABasicAnimation.
*/
*/
...
@@ -586,4 +615,15 @@ extension Motion {
...
@@ -586,4 +615,15 @@ extension Motion {
animation
.
toValue
=
NSNumber
(
floatLiteral
:
Double
(
height
))
animation
.
toValue
=
NSNumber
(
floatLiteral
:
Double
(
height
))
return
animation
return
animation
}
}
/**
Creates a CABasicaAnimation for the height key path.
- Parameter size: A CGSize.
- Returns: A CABasicAnimation.
*/
public
static
func
size
(
_
size
:
CGSize
)
->
CABasicAnimation
{
let
animation
=
CABasicAnimation
(
keyPath
:
.
size
)
animation
.
toValue
=
NSValue
(
cgSize
:
size
)
return
animation
}
}
}
Sources/iOS/MotionTransition.swift
View file @
1e63fdbd
...
@@ -123,7 +123,7 @@ extension UIView {
...
@@ -123,7 +123,7 @@ extension UIView {
open
class
MotionTransitionPresentationController
:
UIPresentationController
{
open
class
MotionTransitionPresentationController
:
UIPresentationController
{
open
override
func
presentationTransitionWillBegin
()
{
open
override
func
presentationTransitionWillBegin
()
{
guard
let
containerView
=
containerView
else
{
guard
nil
!
=
containerView
else
{
return
return
}
}
...
@@ -139,7 +139,7 @@ open class MotionTransitionPresentationController: UIPresentationController {
...
@@ -139,7 +139,7 @@ open class MotionTransitionPresentationController: UIPresentationController {
}
}
open
override
func
dismissalTransitionWillBegin
()
{
open
override
func
dismissalTransitionWillBegin
()
{
guard
let
containerView
=
containerView
else
{
guard
nil
!
=
containerView
else
{
return
return
}
}
...
@@ -161,62 +161,10 @@ open class MotionTransitionPresentationController: UIPresentationController {
...
@@ -161,62 +161,10 @@ open class MotionTransitionPresentationController: UIPresentationController {
open
class
MotionTransitionDelegate
:
NSObject
{
open
class
MotionTransitionDelegate
:
NSObject
{
open
var
isPresenting
=
false
open
var
isPresenting
=
false
open
var
transitionContext
:
UIViewControllerContextTransitioning
!
open
var
containerView
:
UIView
!
open
var
toView
:
UIView
!
open
var
toViews
:
[
UIView
]
{
var
views
:
[
UIView
]
=
0
<
toViewController
.
view
.
motionTransitionIdentifier
.
utf16
.
count
?
[
toViewController
.
view
]
:
[]
subviews
(
of
:
toViewController
.
view
,
views
:
&
views
)
return
views
}
open
var
toViewController
:
UIViewController
!
open
var
toViewController
:
UIViewController
!
open
var
toViewStartFrame
:
CGRect
!
open
var
toViewFinalFrame
:
CGRect
!
open
var
fromView
:
UIView
!
open
var
fromViews
:
[
UIView
]
{
var
views
:
[
UIView
]
=
0
<
fromViewController
.
view
.
motionTransitionIdentifier
.
utf16
.
count
?
[
fromViewController
.
view
]
:
[]
subviews
(
of
:
fromViewController
.
view
,
views
:
&
views
)
return
views
}
open
var
fromViewController
:
UIViewController
!
open
var
fromViewController
:
UIViewController
!
open
var
fromViewFinalFrame
:
CGRect
!
}
extension
MotionTransitionDelegate
{
@objc(animateTransition:)
open
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
}
@objc(transitionDuration:)
open
func
transitionDuration
(
using
transitionContext
:
UIViewControllerContextTransitioning
?)
->
TimeInterval
{
return
0.25
}
open
func
animationEnded
(
_
transitionCompleted
:
Bool
)
{
// print("MotionTransitionAnimator", #function)
}
}
extension
MotionTransitionDelegate
{
fileprivate
func
subviews
(
of
view
:
UIView
,
views
:
inout
[
UIView
])
{
for
v
in
view
.
subviews
{
if
0
<
v
.
motionTransitionIdentifier
.
utf16
.
count
{
views
.
append
(
v
)
}
subviews
(
of
:
v
,
views
:
&
views
)
}
}
}
}
extension
MotionTransitionDelegate
:
UIViewControllerTransitioningDelegate
{
extension
MotionTransitionDelegate
:
UIViewControllerTransitioningDelegate
{
...
@@ -266,36 +214,32 @@ extension MotionTransitionDelegate: UITabBarControllerDelegate {
...
@@ -266,36 +214,32 @@ extension MotionTransitionDelegate: UITabBarControllerDelegate {
}
}
}
}
open
class
MotionTransitionInteractiveDelegate
:
UIPercentDrivenInteractiveTransition
{
open
class
MotionTransitionAnimator
:
MotionTransitionDelegate
{
open
var
isPresenting
=
false
open
var
transitionContext
:
UIViewControllerContextTransitioning
!
open
var
transitionContext
:
UIViewControllerContextTransitioning
!
open
var
containerView
:
UIView
!
open
var
delay
:
TimeInterval
=
0
open
var
duration
:
TimeInterval
=
0
open
var
toView
:
UIView
!
open
var
toViewController
:
UIViewController
!
open
var
toViewStartFrame
:
CGRect
!
open
var
toViewFinalFrame
:
CGRect
!
open
var
fromView
:
UIView
!
open
var
containerView
:
UIView
!
open
var
fromViewController
:
UIViewController
!
open
var
transitionView
=
UIView
()
open
var
fromViewFinalFrame
:
CGRect
!
open
var
panGesture
:
UIPanGestureRecognizer
!
@objc(startInteractiveTransition:)
open
override
func
startInteractiveTransition
(
_
transitionContext
:
UIViewControllerContextTransitioning
)
{
super
.
startInteractiveTransition
(
transitionContext
)
guard
let
tView
=
transitionContext
.
view
(
forKey
:
.
to
)
else
{
public
var
toViews
:
[
UIView
]
{
return
var
views
:
[
UIView
]
=
0
<
toViewController
.
view
.
motionTransitionIdentifier
.
utf16
.
count
?
[
toViewController
.
view
]
:
[]
subviews
(
of
:
toViewController
.
view
,
views
:
&
views
)
return
views
}
}
guard
let
tVC
=
transitionContext
.
viewController
(
forKey
:
.
to
)
else
{
public
var
fromViews
:
[
UIView
]
{
return
var
views
:
[
UIView
]
=
0
<
fromViewController
.
view
.
motionTransitionIdentifier
.
utf16
.
count
?
[
fromViewController
.
view
]
:
[]
subviews
(
of
:
fromViewController
.
view
,
views
:
&
views
)
return
views
}
}
}
guard
let
fView
=
transitionContext
.
view
(
forKey
:
.
from
)
else
{
extension
MotionTransitionAnimator
:
UIViewControllerAnimatedTransitioning
{
@objc(animateTransition:)
open
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
guard
let
tVC
=
transitionContext
.
viewController
(
forKey
:
.
to
)
else
{
return
return
}
}
...
@@ -306,166 +250,79 @@ open class MotionTransitionInteractiveDelegate: UIPercentDrivenInteractiveTransi
...
@@ -306,166 +250,79 @@ open class MotionTransitionInteractiveDelegate: UIPercentDrivenInteractiveTransi
self
.
transitionContext
=
transitionContext
self
.
transitionContext
=
transitionContext
containerView
=
transitionContext
.
containerView
containerView
=
transitionContext
.
containerView
containerView
.
addSubview
(
transitionView
)
transitionView
.
frame
=
containerView
.
bounds
toView
=
tView
toViewController
=
tVC
toViewController
=
tVC
fromView
=
fView
fromViewController
=
fVC
fromViewController
=
fVC
toViewStartFrame
=
transitionContext
.
initialFrame
(
for
:
toViewController
)
toViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
toViewController
)
fromViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
fromViewController
)
preparePanGesture
()
}
open
func
animationEnded
(
_
transitionCompleted
:
Bool
)
{
// print("MotionTransitionAnimator", #function)
}
}
}
extension
MotionTransitionInteractiveDelegate
{
@objc(transitionDuration:)
fileprivate
func
preparePanGesture
()
{
open
func
transitionDuration
(
using
transitionContext
:
UIViewControllerContextTransitioning
?)
->
TimeInterval
{
panGesture
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
#selector(
handlePanGesture(recognizer:)
)
)
return
delay
+
duration
panGesture
.
maximumNumberOfTouches
=
1
containerView
.
addGestureRecognizer
(
panGesture
)
}
}
}
}
extension
MotionTransitionInteractiveDelegate
{
extension
MotionTransitionDelegate
{
@objc
fileprivate
func
subviews
(
of
view
:
UIView
,
views
:
inout
[
UIView
])
{
fileprivate
func
handlePanGesture
(
recognizer
:
UIPanGestureRecognizer
)
{
for
v
in
view
.
subviews
{
switch
recognizer
.
state
{
if
0
<
v
.
motionTransitionIdentifier
.
utf16
.
count
{
case
.
began
:
views
.
append
(
v
)
panGesture
.
setTranslation
(
.
zero
,
in
:
containerView
)
case
.
changed
:
let
translation
=
panGesture
.
translation
(
in
:
containerView
)
/**
Compute how far the gesture recognizer tranveled on the
vertical axis.
*/
let
percentageComplete
=
fabs
(
translation
.
y
/
containerView
.
bounds
.
height
)
update
(
percentageComplete
)
case
.
ended
:
finish
()
containerView
.
removeGestureRecognizer
(
panGesture
)
default
:
break
}
}
subviews
(
of
:
v
,
views
:
&
views
)
}
}
}
open
class
MotionTransitionAnimator
:
MotionTransitionDelegate
,
UIViewControllerAnimatedTransitioning
{
@objc(animateTransition:)
open
override
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
// guard let tView = transitionContext.view(forKey: .to) else {
// return
// }
guard
let
tVC
=
transitionContext
.
viewController
(
forKey
:
.
to
)
else
{
return
}
}
// guard let fView = transitionContext.view(forKey: .from) else {
fileprivate
func
snapshotView
(
for
view
:
UIView
)
->
UIView
{
// return
view
.
isHidden
=
false
// }
guard
let
fVC
=
transitionContext
.
viewController
(
forKey
:
.
from
)
else
{
// capture a snapshot without cornerRadius
return
let
oldCornerRadius
=
view
.
cornerRadius
}
view
.
cornerRadius
=
0
let
v
=
view
.
snapshotView
(
afterScreenUpdates
:
false
)
!
self
.
transitionContext
=
transitionContext
view
.
cornerRadius
=
oldCornerRadius
containerView
=
transitionContext
.
containerView
// toView = tView
let
contentView
=
v
.
subviews
.
first
!
toViewController
=
tVC
contentView
.
cornerRadius
=
view
.
cornerRadius
contentView
.
masksToBounds
=
true
// fromView = fView
v
.
motionTransitionIdentifier
=
view
.
motionTransitionIdentifier
fromViewController
=
fVC
v
.
cornerRadius
=
view
.
cornerRadius
v
.
zPosition
=
view
.
zPosition
v
.
opacity
=
view
.
opacity
v
.
isOpaque
=
view
.
isOpaque
v
.
anchorPoint
=
view
.
anchorPoint
v
.
layer
.
masksToBounds
=
view
.
layer
.
masksToBounds
v
.
borderColor
=
view
.
borderColor
v
.
borderWidth
=
view
.
borderWidth
v
.
shadowRadius
=
view
.
shadowRadius
v
.
shadowOpacity
=
view
.
shadowOpacity
v
.
shadowColor
=
view
.
shadowColor
v
.
shadowOffset
=
view
.
shadowOffset
toViewStartFrame
=
transitionContext
.
initialFrame
(
for
:
toViewController
)
v
.
layer
.
transform
=
view
.
layer
.
transform
toViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
toViewController
)
fromViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
fromViewController
)
v
ar
duration
=
transitionDuration
(
using
:
nil
)
v
iew
.
isHidden
=
true
transitionContext
.
containerView
.
addSubview
(
toViewController
.
view
)
return
v
for
v
in
toViews
{
if
0
<
v
.
motionTransitionIdentifier
.
utf16
.
count
{
for
a
in
v
.
motionTransitionAnimations
{
switch
a
{
case
let
.
duration
(
dur
):
if
dur
>
duration
{
duration
=
dur
}
default
:
break
}
}
v
.
motion
(
v
.
motionTransitionAnimations
)
}
}
Motion
.
delay
(
duration
)
{
transitionContext
.
completeTransition
(
!
transitionContext
.
transitionWasCancelled
)
}
}
}
}
}
open
class
MotionTransitionPresentedAnimator
:
MotionTransition
Delegate
,
UIViewControllerAnimatedTransitioning
{
open
class
MotionTransitionPresentedAnimator
:
MotionTransition
Animator
{
@objc(animateTransition:)
@objc(animateTransition:)
open
override
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
open
override
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
// guard let tView = transitionContext.view(forKey: .to) else {
super
.
animateTransition
(
using
:
transitionContext
)
// return
// }
guard
let
tVC
=
transitionContext
.
viewController
(
forKey
:
.
to
)
else
{
return
}
// guard let fView = transitionContext.view(forKey: .from) else {
// return
// }
guard
let
fVC
=
transitionContext
.
viewController
(
forKey
:
.
from
)
else
{
return
}
self
.
transitionContext
=
transitionContext
containerView
=
transitionContext
.
containerView
// toView = tView
for
toView
in
toViews
{
toViewController
=
tVC
for
fromView
in
fromViews
{
if
toView
.
motionTransitionIdentifier
==
fromView
.
motionTransitionIdentifier
{
// fromView = fView
fromViewController
=
fVC
toViewStartFrame
=
transitionContext
.
initialFrame
(
for
:
toViewController
)
toViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
toViewController
)
fromViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
fromViewController
)
var
delay
:
TimeInterval
=
0
var
duration
=
transitionDuration
(
using
:
nil
)
transitionContext
.
containerView
.
addSubview
(
toViewController
.
view
)
for
v
in
toViews
{
for
v2
in
fromViews
{
if
v
.
motionTransitionIdentifier
==
v2
.
motionTransitionIdentifier
{
var
t
:
TimeInterval
=
0
var
t
:
TimeInterval
=
0
var
d
:
TimeInterval
=
0
var
d
:
TimeInterval
=
0
var
a
=
[
CABasicAnimation
]()
var
a
=
[
CABasicAnimation
]()
var
tf
=
MotionAnimationTimingFunction
.
easeInEaseOut
var
tf
=
MotionAnimationTimingFunction
.
easeInEaseOut
var
w
:
CGFloat
=
0
for
ta
in
toView
.
motionTransitionAnimations
{
var
h
:
CGFloat
=
0
for
ta
in
v
.
motionTransitionAnimations
{
switch
ta
{
switch
ta
{
case
let
.
delay
(
time
):
case
let
.
delay
(
time
):
if
time
>
delay
{
if
time
>
delay
{
...
@@ -477,55 +334,38 @@ open class MotionTransitionPresentedAnimator: MotionTransitionDelegate, UIViewCo
...
@@ -477,55 +334,38 @@ open class MotionTransitionPresentedAnimator: MotionTransitionDelegate, UIViewCo
duration
=
time
duration
=
time
}
}
d
=
time
d
=
time
case
let
.
width
(
width
):
w
=
width
case
let
.
height
(
height
):
h
=
height
default
:
break
default
:
break
}
}
}
}
// var w: CGFloat = toView.bounds.width
// var h: CGFloat = toView.bounds.height
// var px: CGFloat = toView.position.x + w / 2
// var py: CGFloat = toView.position.y + h / 2
// a.append(Motion.position(x: px, y: py))
// a.append(Motion.width(w))
// a.append(Motion.height(h))
var
px
:
CGFloat
=
v
.
position
.
x
// let rotate = Motion.rotate(angle: toView.layer.value(forKeyPath: MotionAnimationKeyPath.rotation.rawValue) as? CGFloat ?? 0)
var
py
:
CGFloat
=
v
.
position
.
y
// rotate.fromValue = fromView.layer.value(forKeyPath: MotionAnimationKeyPath.rotation.rawValue)
// a.append(rotate)
for
ta
in
v
.
motionTransitionAnimations
{
a
.
append
(
Motion
.
background
(
color
:
toView
.
backgroundColor
??
.
clear
))
switch
ta
{
// a.append(Motion.corner(radius: toView.cornerRadius))
case
let
.
x
(
x
):
px
=
x
+
w
/
2
let
snapshot
=
snapshotView
(
for
:
fromView
)
case
let
.
y
(
y
):
snapshot
.
isHidden
=
false
py
=
y
+
h
/
2
snapshot
.
bounds
=
fromView
.
bounds
case
let
.
point
(
x
,
y
):
snapshot
.
position
=
fromView
.
superview
?
.
convert
(
fromView
.
position
,
to
:
nil
)
??
fromView
.
position
px
=
x
+
w
/
2
transitionView
.
addSubview
(
snapshot
)
py
=
y
+
h
/
2
default
:
break
}
}
Motion
.
delay
(
t
)
{
Motion
.
delay
(
t
)
{
for
ta
in
v
.
motionTransitionAnimations
{
for
ta
in
toView
.
motionTransitionAnimations
{
switch
ta
{
switch
ta
{
case
let
.
timingFunction
(
timingFunction
):
case
let
.
timingFunction
(
timingFunction
):
tf
=
timingFunction
tf
=
timingFunction
case
let
.
rotate
(
angle
):
let
rotate
=
Motion
.
rotate
(
angle
:
angle
)
let
radians
=
CGFloat
(
atan2f
(
Float
(
v2
.
transform
.
b
),
Float
(
v2
.
transform
.
a
)))
rotate
.
fromValue
=
v2
.
layer
.
value
(
forKeyPath
:
MotionAnimationKeyPath
.
rotation
.
rawValue
)
a
.
append
(
rotate
)
case
let
.
backgroundColor
(
color
):
a
.
append
(
Motion
.
background
(
color
:
color
))
case
let
.
corners
(
radius
):
a
.
append
(
Motion
.
corner
(
radius
:
radius
))
case
let
.
x
(
_
),
.
y
(
_
),
.
point
(
_
,
_
):
a
.
append
(
Motion
.
position
(
to
:
CGPoint
(
x
:
px
,
y
:
py
)))
case
let
.
position
(
x
,
y
):
a
.
append
(
Motion
.
position
(
to
:
CGPoint
(
x
:
x
,
y
:
y
)))
case
let
.
shadow
(
path
):
case
let
.
shadow
(
path
):
a
.
append
(
Motion
.
shadow
(
path
:
path
))
a
.
append
(
Motion
.
shadow
(
path
:
path
))
case
let
.
width
(
w
):
a
.
append
(
Motion
.
width
(
w
))
case
let
.
height
(
h
):
a
.
append
(
Motion
.
height
(
h
))
default
:
break
default
:
break
}
}
}
}
...
@@ -535,53 +375,31 @@ open class MotionTransitionPresentedAnimator: MotionTransitionDelegate, UIViewCo
...
@@ -535,53 +375,31 @@ open class MotionTransitionPresentedAnimator: MotionTransitionDelegate, UIViewCo
g
.
isRemovedOnCompletion
=
false
g
.
isRemovedOnCompletion
=
false
g
.
timingFunction
=
MotionAnimationTimingFunctionToValue
(
timingFunction
:
tf
)
g
.
timingFunction
=
MotionAnimationTimingFunctionToValue
(
timingFunction
:
tf
)
v
.
animate
(
g
)
snapshot
.
animate
(
g
)
}
}
}
}
}
}
}
}
Motion
.
delay
(
delay
+
duration
)
{
Motion
.
delay
(
transitionDuration
(
using
:
transitionContext
))
{
[
weak
self
]
in
defer
{
transitionContext
.
completeTransition
(
!
transitionContext
.
transitionWasCancelled
)
transitionContext
.
completeTransition
(
!
transitionContext
.
transitionWasCancelled
)
}
}
}
}
open
class
MotionTransitionDismissedAnimator
:
MotionTransitionDelegate
,
UIViewControllerAnimatedTransitioning
{
@objc(animateTransition:)
open
override
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
// guard let tView = transitionContext.view(forKey: .to) else {
// return
// }
guard
let
tVC
=
transitionContext
.
viewController
(
forKey
:
.
to
)
else
{
guard
let
s
=
self
else
{
return
return
}
}
// guard let fView = transitionContext.view(forKey: .from) else {
// s.transitionView.removeFromSuperview()
// return
s
.
containerView
.
addSubview
(
s
.
toViewController
.
view
)
// }
guard
let
fVC
=
transitionContext
.
viewController
(
forKey
:
.
from
)
else
{
return
}
}
}
}
self
.
transitionContext
=
transitionContext
open
class
MotionTransitionDismissedAnimator
:
MotionTransitionAnimator
{
@objc(animateTransition:)
containerView
=
transitionContext
.
containerView
open
override
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
super
.
animateTransition
(
using
:
transitionContext
)
// toView = tView
toViewController
=
tVC
// fromView = fView
fromViewController
=
fVC
toViewStartFrame
=
transitionContext
.
initialFrame
(
for
:
toViewController
)
toViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
toViewController
)
fromViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
fromViewController
)
var
delay
:
TimeInterval
=
0
var
duration
=
transitionDuration
(
using
:
nil
)
for
v
in
fromViews
{
for
v
in
fromViews
{
for
v2
in
toViews
{
for
v2
in
toViews
{
...
@@ -606,22 +424,22 @@ open class MotionTransitionDismissedAnimator: MotionTransitionDelegate, UIViewCo
...
@@ -606,22 +424,22 @@ open class MotionTransitionDismissedAnimator: MotionTransitionDelegate, UIViewCo
d
=
time
d
=
time
case
let
.
timingFunction
(
timingFunction
):
case
let
.
timingFunction
(
timingFunction
):
tf
=
timingFunction
tf
=
timingFunction
case
let
.
rotate
(
angle
):
case
.
rotate
(
_
):
let
radians
=
CGFloat
(
atan2f
(
Float
(
v2
.
transform
.
b
),
Float
(
v2
.
transform
.
a
)))
let
radians
=
CGFloat
(
atan2f
(
Float
(
v2
.
transform
.
b
),
Float
(
v2
.
transform
.
a
)))
let
rotate
=
Motion
.
rotate
(
angle
:
radians
*
180
/
CGFloat
(
M_PI
))
let
rotate
=
Motion
.
rotate
(
angle
:
radians
*
180
/
CGFloat
(
M_PI
))
rotate
.
fromValue
=
v
.
layer
.
value
(
forKeyPath
:
MotionAnimationKeyPath
.
rotation
.
rawValue
)
rotate
.
fromValue
=
v
.
layer
.
value
(
forKeyPath
:
MotionAnimationKeyPath
.
rotation
.
rawValue
)
a
.
append
(
rotate
)
a
.
append
(
rotate
)
case
let
.
backgroundColor
(
color
):
case
.
backgroundColor
(
_
):
a
.
append
(
Motion
.
background
(
color
:
.
clear
))
a
.
append
(
Motion
.
background
(
color
:
.
clear
))
case
let
.
corners
(
radius
):
case
.
corners
(
_
):
a
.
append
(
Motion
.
corner
(
radius
:
v2
.
cornerRadius
))
a
.
append
(
Motion
.
corner
(
radius
:
v2
.
cornerRadius
))
case
let
.
x
(
_
),
.
y
(
_
),
.
point
(
_
,
_
),
.
position
(
_
,
_
):
case
.
x
(
_
),
.
y
(
_
),
.
point
(
_
,
_
),
.
position
(
_
,
_
):
a
.
append
(
Motion
.
position
(
to
:
nil
==
v2
.
superview
?
v2
.
position
:
v2
.
superview
!.
convert
(
v2
.
position
,
to
:
nil
)))
a
.
append
(
Motion
.
position
(
to
:
nil
==
v2
.
superview
?
v2
.
position
:
v2
.
superview
!.
convert
(
v2
.
position
,
to
:
nil
)))
case
let
.
shadow
(
path
):
case
let
.
shadow
(
path
):
a
.
append
(
Motion
.
shadow
(
path
:
path
))
a
.
append
(
Motion
.
shadow
(
path
:
path
))
case
let
.
width
(
w
):
case
.
width
(
_
):
a
.
append
(
Motion
.
width
(
v2
.
bounds
.
width
))
a
.
append
(
Motion
.
width
(
v2
.
bounds
.
width
))
case
let
.
height
(
h
):
case
.
height
(
_
):
a
.
append
(
Motion
.
height
(
v2
.
bounds
.
height
))
a
.
append
(
Motion
.
height
(
v2
.
bounds
.
height
))
default
:
break
default
:
break
}
}
...
@@ -651,3 +469,94 @@ open class MotionTransitionInteractiveAnimator: MotionTransitionInteractiveDeleg
...
@@ -651,3 +469,94 @@ open class MotionTransitionInteractiveAnimator: MotionTransitionInteractiveDeleg
}
}
}
}
open
class
MotionTransitionInteractiveDelegate
:
UIPercentDrivenInteractiveTransition
{
open
var
isPresenting
=
false
open
var
transitionContext
:
UIViewControllerContextTransitioning
!
open
var
containerView
:
UIView
!
open
var
toView
:
UIView
!
open
var
toViewController
:
UIViewController
!
open
var
toViewStartFrame
:
CGRect
!
open
var
toViewFinalFrame
:
CGRect
!
open
var
fromView
:
UIView
!
open
var
fromViewController
:
UIViewController
!
open
var
fromViewFinalFrame
:
CGRect
!
open
var
panGesture
:
UIPanGestureRecognizer
!
@objc(startInteractiveTransition:)
open
override
func
startInteractiveTransition
(
_
transitionContext
:
UIViewControllerContextTransitioning
)
{
super
.
startInteractiveTransition
(
transitionContext
)
guard
let
tView
=
transitionContext
.
view
(
forKey
:
.
to
)
else
{
return
}
guard
let
tVC
=
transitionContext
.
viewController
(
forKey
:
.
to
)
else
{
return
}
guard
let
fView
=
transitionContext
.
view
(
forKey
:
.
from
)
else
{
return
}
guard
let
fVC
=
transitionContext
.
viewController
(
forKey
:
.
from
)
else
{
return
}
self
.
transitionContext
=
transitionContext
containerView
=
transitionContext
.
containerView
toView
=
tView
toViewController
=
tVC
fromView
=
fView
fromViewController
=
fVC
toViewStartFrame
=
transitionContext
.
initialFrame
(
for
:
toViewController
)
toViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
toViewController
)
fromViewFinalFrame
=
transitionContext
.
finalFrame
(
for
:
fromViewController
)
preparePanGesture
()
}
open
func
animationEnded
(
_
transitionCompleted
:
Bool
)
{
// print("MotionTransitionAnimator", #function)
}
}
extension
MotionTransitionInteractiveDelegate
{
fileprivate
func
preparePanGesture
()
{
panGesture
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
#selector(
handlePanGesture(recognizer:)
)
)
panGesture
.
maximumNumberOfTouches
=
1
containerView
.
addGestureRecognizer
(
panGesture
)
}
}
extension
MotionTransitionInteractiveDelegate
{
@objc
fileprivate
func
handlePanGesture
(
recognizer
:
UIPanGestureRecognizer
)
{
switch
recognizer
.
state
{
case
.
began
:
panGesture
.
setTranslation
(
.
zero
,
in
:
containerView
)
case
.
changed
:
let
translation
=
panGesture
.
translation
(
in
:
containerView
)
/**
Compute how far the gesture recognizer tranveled on the
vertical axis.
*/
let
percentageComplete
=
fabs
(
translation
.
y
/
containerView
.
bounds
.
height
)
update
(
percentageComplete
)
case
.
ended
:
finish
()
containerView
.
removeGestureRecognizer
(
panGesture
)
default
:
break
}
}
}
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