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
936c5b62
Unverified
Commit
936c5b62
authored
Jun 11, 2017
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reworked IgnoreSubviewTransitionsPreprocessor
parent
b6de5705
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
78 additions
and
461 deletions
+78
-461
Motion.xcodeproj/project.pbxproj
+0
-16
Sources/Debug Plugin/MotionDebugPlugin.swift
+0
-185
Sources/Debug Plugin/MotionDebugView.swift
+0
-198
Sources/MotionController.swift
+1
-1
Sources/MotionPlugin.swift
+3
-3
Sources/MotionTransition.swift
+1
-1
Sources/Preprocessors/CascadePreprocessor.swift
+2
-3
Sources/Preprocessors/DurationPreprocessor.swift
+1
-1
Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift
+40
-23
Sources/TransitionPreprocessor.swift
+30
-30
No files found.
Motion.xcodeproj/project.pbxproj
View file @
936c5b62
...
...
@@ -20,8 +20,6 @@
96AEB68E1EE4610F009A3BE0
/* MotionCoreAnimationViewContext.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6661EE4610F009A3BE0
/* MotionCoreAnimationViewContext.swift */
;
};
96AEB68F1EE4610F009A3BE0
/* MotionDefaultAnimator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6671EE4610F009A3BE0
/* MotionDefaultAnimator.swift */
;
};
96AEB6901EE4610F009A3BE0
/* MotionViewPropertyViewContext.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB6681EE4610F009A3BE0
/* MotionViewPropertyViewContext.swift */
;
};
96AEB6911EE4610F009A3BE0
/* MotionDebugPlugin.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB66A1EE4610F009A3BE0
/* MotionDebugPlugin.swift */
;
};
96AEB6921EE4610F009A3BE0
/* MotionDebugView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB66B1EE4610F009A3BE0
/* MotionDebugView.swift */
;
};
96AEB6931EE4610F009A3BE0
/* TransitionPreprocessor.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB66C1EE4610F009A3BE0
/* TransitionPreprocessor.swift */
;
};
96AEB6941EE4610F009A3BE0
/* Motion+Array.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB66E1EE4610F009A3BE0
/* Motion+Array.swift */
;
};
96AEB6951EE4610F009A3BE0
/* Motion+CALayer.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96AEB66F1EE4610F009A3BE0
/* Motion+CALayer.swift */
;
};
...
...
@@ -58,8 +56,6 @@
96AEB6661EE4610F009A3BE0
/* MotionCoreAnimationViewContext.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionCoreAnimationViewContext.swift
;
sourceTree
=
"<group>"
;
};
96AEB6671EE4610F009A3BE0
/* MotionDefaultAnimator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionDefaultAnimator.swift
;
sourceTree
=
"<group>"
;
};
96AEB6681EE4610F009A3BE0
/* MotionViewPropertyViewContext.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionViewPropertyViewContext.swift
;
sourceTree
=
"<group>"
;
};
96AEB66A1EE4610F009A3BE0
/* MotionDebugPlugin.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionDebugPlugin.swift
;
sourceTree
=
"<group>"
;
};
96AEB66B1EE4610F009A3BE0
/* MotionDebugView.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionDebugView.swift
;
sourceTree
=
"<group>"
;
};
96AEB66C1EE4610F009A3BE0
/* TransitionPreprocessor.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
name
=
TransitionPreprocessor.swift
;
path
=
../TransitionPreprocessor.swift
;
sourceTree
=
"<group>"
;
};
96AEB66E1EE4610F009A3BE0
/* Motion+Array.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"Motion+Array.swift"
;
sourceTree
=
"<group>"
;
};
96AEB66F1EE4610F009A3BE0
/* Motion+CALayer.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"Motion+CALayer.swift"
;
sourceTree
=
"<group>"
;
};
...
...
@@ -112,15 +108,6 @@
path
=
Animator
;
sourceTree
=
"<group>"
;
};
96AEB6691EE4610F009A3BE0
/* Debug Plugin */
=
{
isa
=
PBXGroup
;
children
=
(
96AEB66A1EE4610F009A3BE0
/* MotionDebugPlugin.swift */
,
96AEB66B1EE4610F009A3BE0
/* MotionDebugView.swift */
,
);
path
=
"Debug Plugin"
;
sourceTree
=
"<group>"
;
};
96AEB66D1EE4610F009A3BE0
/* Extensions */
=
{
isa
=
PBXGroup
;
children
=
(
...
...
@@ -184,7 +171,6 @@
96E49A3F1EEA08F8006D5A93
/* MotionTransitionObserver.swift */
,
96AEB67D1EE4610F009A3BE0
/* MotionPlugin.swift */
,
96AEB6641EE4610F009A3BE0
/* Animator */
,
96AEB6691EE4610F009A3BE0
/* Debug Plugin */
,
96AEB66D1EE4610F009A3BE0
/* Extensions */
,
96AEB6861EE4610F009A3BE0
/* Preprocessors */
,
);
...
...
@@ -286,7 +272,6 @@
96AEB6941EE4610F009A3BE0
/* Motion+Array.swift in Sources */
,
96AEB6951EE4610F009A3BE0
/* Motion+CALayer.swift in Sources */
,
96AEB68E1EE4610F009A3BE0
/* MotionCoreAnimationViewContext.swift in Sources */
,
96AEB6921EE4610F009A3BE0
/* MotionDebugView.swift in Sources */
,
96E49A401EEA08F8006D5A93
/* MotionTransitionObserver.swift in Sources */
,
96AEB6A01EE4610F009A3BE0
/* MotionIndependentController.swift in Sources */
,
966A7F091EEC422000A2DAAC
/* MotionSnapshotType.swift in Sources */
,
...
...
@@ -298,7 +283,6 @@
96AEB6AE1EE4610F009A3BE0
/* IgnoreSubviewModifiersPreprocessor.swift in Sources */
,
96AEB68D1EE4610F009A3BE0
/* MotionAnimatorViewContext.swift in Sources */
,
96AEB6B01EE4610F009A3BE0
/* SourcePreprocessor.swift in Sources */
,
96AEB6911EE4610F009A3BE0
/* MotionDebugPlugin.swift in Sources */
,
963150D21EE50DA6002B0D42
/* Motion+Obj-C.swift in Sources */
,
96AEB6AF1EE4610F009A3BE0
/* MatchPreprocessor.swift in Sources */
,
96AEB69E1EE4610F009A3BE0
/* MotionController.swift in Sources */
,
...
...
Sources/Debug Plugin/MotionDebugPlugin.swift
deleted
100644 → 0
View file @
b6de5705
/*
* 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
UIKit
#if os(iOS)
public
class
MotionDebugPlugin
:
MotionPlugin
{
public
static
var
showOnTop
:
Bool
=
false
var
debugView
:
MotionDebugView
?
var
zPositionMap
=
[
UIView
:
CGFloat
]()
var
addedLayers
:
[
CALayer
]
=
[]
var
updating
=
false
override
public
func
animate
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
->
TimeInterval
{
if
Motion
.
shared
.
forceNonInteractive
{
return
0
}
var
hasArc
=
false
for
v
in
context
.
fromViews
+
context
.
toViews
where
context
[
v
]?
.
arc
!=
nil
&&
context
[
v
]?
.
position
!=
nil
{
hasArc
=
true
break
}
let
debugView
=
MotionDebugView
(
initialProcess
:
Motion
.
shared
.
isPresenting
?
0.0
:
1.0
,
showCurveButton
:
hasArc
,
showOnTop
:
MotionDebugPlugin
.
showOnTop
)
debugView
.
frame
=
Motion
.
shared
.
container
.
bounds
debugView
.
delegate
=
self
UIApplication
.
shared
.
keyWindow
!.
addSubview
(
debugView
)
debugView
.
layoutSubviews
()
self
.
debugView
=
debugView
UIView
.
animate
(
withDuration
:
0.4
)
{
debugView
.
showControls
=
true
}
return
.
infinity
}
public
override
func
resume
(
at
:
TimeInterval
,
isReversed
:
Bool
)
->
TimeInterval
{
guard
let
debugView
=
debugView
else
{
return
0.4
}
debugView
.
delegate
=
nil
UIView
.
animate
(
withDuration
:
0.4
)
{
debugView
.
showControls
=
false
debugView
.
debugSlider
.
setValue
(
roundf
(
debugView
.
progress
),
animated
:
true
)
}
on3D
(
wants3D
:
false
)
return
0.4
}
public
override
func
clean
()
{
debugView
?
.
removeFromSuperview
()
debugView
=
nil
}
}
extension
MotionDebugPlugin
:
MotionDebugViewDelegate
{
public
func
onDone
()
{
guard
let
debugView
=
debugView
else
{
return
}
let
seekValue
=
Motion
.
shared
.
isPresenting
?
debugView
.
progress
:
1.0
-
debugView
.
progress
if
seekValue
>
0.5
{
Motion
.
shared
.
end
()
}
else
{
Motion
.
shared
.
cancel
()
}
}
public
func
onProcessSliderChanged
(
progress
:
Float
)
{
let
seekValue
=
Motion
.
shared
.
isPresenting
?
progress
:
1.0
-
progress
Motion
.
shared
.
update
(
elapsedTime
:
Double
(
seekValue
))
}
func
onPerspectiveChanged
(
translation
:
CGPoint
,
rotate
:
CGFloat
,
scale
:
CGFloat
)
{
var
t
=
CATransform3DIdentity
t
.
m34
=
-
1
/
4000
t
=
CATransform3DTranslate
(
t
,
translation
.
x
,
translation
.
y
,
0
)
t
=
CATransform3DScale
(
t
,
scale
,
scale
,
1
)
t
=
CATransform3DRotate
(
t
,
rotate
,
0
,
1
,
0
)
Motion
.
shared
.
container
.
layer
.
sublayerTransform
=
t
}
func
animateZPosition
(
view
:
UIView
,
to
:
CGFloat
)
{
let
a
=
CABasicAnimation
(
keyPath
:
"zPosition"
)
a
.
fromValue
=
view
.
layer
.
value
(
forKeyPath
:
"zPosition"
)
a
.
toValue
=
NSNumber
(
value
:
Double
(
to
))
a
.
timingFunction
=
CAMediaTimingFunction
(
name
:
kCAMediaTimingFunctionEaseInEaseOut
)
a
.
duration
=
0.4
view
.
layer
.
add
(
a
,
forKey
:
"zPosition"
)
view
.
layer
.
zPosition
=
to
}
func
onDisplayArcCurve
(
wantsCurve
:
Bool
)
{
for
layer
in
addedLayers
{
layer
.
removeFromSuperlayer
()
addedLayers
.
removeAll
()
}
if
wantsCurve
{
for
layer
in
Motion
.
shared
.
container
.
layer
.
sublayers
!
{
for
(
_
,
anim
)
in
layer
.
animations
{
if
let
keyframeAnim
=
anim
as?
CAKeyframeAnimation
,
let
path
=
keyframeAnim
.
path
{
let
s
=
CAShapeLayer
()
s
.
zPosition
=
layer
.
zPosition
+
10
s
.
path
=
path
s
.
strokeColor
=
UIColor
.
blue
.
cgColor
s
.
fillColor
=
UIColor
.
clear
.
cgColor
Motion
.
shared
.
container
.
layer
.
addSublayer
(
s
)
addedLayers
.
append
(
s
)
}
}
}
}
}
func
on3D
(
wants3D
:
Bool
)
{
var
t
=
CATransform3DIdentity
if
wants3D
{
var
viewsWithZPosition
=
Set
<
UIView
>
()
for
view
in
Motion
.
shared
.
container
.
subviews
where
view
.
layer
.
zPosition
!=
0
{
viewsWithZPosition
.
insert
(
view
)
zPositionMap
[
view
]
=
view
.
layer
.
zPosition
}
let
viewsWithoutZPosition
=
Motion
.
shared
.
container
.
subviews
.
filter
{
return
!
viewsWithZPosition
.
contains
(
$0
)
}
let
viewsWithPositiveZPosition
=
viewsWithZPosition
.
filter
{
return
$0
.
layer
.
zPosition
>
0
}
for
(
i
,
v
)
in
viewsWithoutZPosition
.
enumerated
()
{
animateZPosition
(
view
:
v
,
to
:
CGFloat
(
i
*
10
))
}
var
maxZPosition
:
CGFloat
=
0
for
v
in
viewsWithPositiveZPosition
{
maxZPosition
=
max
(
maxZPosition
,
v
.
layer
.
zPosition
)
animateZPosition
(
view
:
v
,
to
:
v
.
layer
.
zPosition
+
CGFloat
(
viewsWithoutZPosition
.
count
*
10
))
}
t
.
m34
=
-
1
/
4000
t
=
CATransform3DTranslate
(
t
,
debugView
!.
translation
.
x
,
debugView
!.
translation
.
y
,
0
)
t
=
CATransform3DScale
(
t
,
debugView
!.
scale
,
debugView
!.
scale
,
1
)
t
=
CATransform3DRotate
(
t
,
debugView
!.
rotate
,
0
,
1
,
0
)
}
else
{
for
v
in
Motion
.
shared
.
container
.
subviews
{
animateZPosition
(
view
:
v
,
to
:
self
.
zPositionMap
[
v
]
??
0
)
}
self
.
zPositionMap
.
removeAll
()
}
let
a
=
CABasicAnimation
(
keyPath
:
"sublayerTransform"
)
a
.
fromValue
=
Motion
.
shared
.
container
.
layer
.
value
(
forKeyPath
:
"sublayerTransform"
)
a
.
toValue
=
NSValue
(
caTransform3D
:
t
)
a
.
timingFunction
=
CAMediaTimingFunction
(
name
:
kCAMediaTimingFunctionEaseInEaseOut
)
a
.
duration
=
0.4
UIView
.
animate
(
withDuration
:
0.4
)
{
self
.
context
.
container
.
backgroundColor
=
UIColor
(
white
:
0.85
,
alpha
:
1.0
)
}
Motion
.
shared
.
container
.
layer
.
add
(
a
,
forKey
:
"debug"
)
Motion
.
shared
.
container
.
layer
.
sublayerTransform
=
t
}
}
#endif
Sources/Debug Plugin/MotionDebugView.swift
deleted
100644 → 0
View file @
b6de5705
/*
* 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
UIKit
#if os(iOS)
protocol
MotionDebugViewDelegate
:
class
{
func
onProcessSliderChanged
(
progress
:
Float
)
func
onPerspectiveChanged
(
translation
:
CGPoint
,
rotate
:
CGFloat
,
scale
:
CGFloat
)
func
on3D
(
wants3D
:
Bool
)
func
onDisplayArcCurve
(
wantsCurve
:
Bool
)
func
onDone
()
}
class
MotionDebugView
:
UIView
{
var
backgroundView
:
UIView
!
var
debugSlider
:
UISlider
!
var
perspectiveButton
:
UIButton
!
var
doneButton
:
UIButton
!
var
arcCurveButton
:
UIButton
?
weak
var
delegate
:
MotionDebugViewDelegate
?
var
panGR
:
UIPanGestureRecognizer
!
var
pinchGR
:
UIPinchGestureRecognizer
!
var
showControls
:
Bool
=
false
{
didSet
{
layoutSubviews
()
}
}
var
showOnTop
:
Bool
=
false
var
rotate
:
CGFloat
=
.
pi
/
6
var
scale
:
CGFloat
=
0.6
var
translation
:
CGPoint
=
.
zero
var
progress
:
Float
{
return
debugSlider
.
value
}
init
(
initialProcess
:
Float
,
showCurveButton
:
Bool
,
showOnTop
:
Bool
)
{
super
.
init
(
frame
:
.
zero
)
self
.
showOnTop
=
showOnTop
backgroundView
=
UIView
(
frame
:
.
zero
)
backgroundView
.
backgroundColor
=
UIColor
(
white
:
1.0
,
alpha
:
0.95
)
backgroundView
.
layer
.
shadowColor
=
UIColor
.
darkGray
.
cgColor
backgroundView
.
layer
.
shadowOpacity
=
0.3
backgroundView
.
layer
.
shadowRadius
=
5
backgroundView
.
layer
.
shadowOffset
=
CGSize
.
zero
addSubview
(
backgroundView
)
doneButton
=
UIButton
(
type
:
.
system
)
doneButton
.
setTitle
(
"Done"
,
for
:
.
normal
)
doneButton
.
addTarget
(
self
,
action
:
#selector(
onDone
)
,
for
:
.
touchUpInside
)
backgroundView
.
addSubview
(
doneButton
)
perspectiveButton
=
UIButton
(
type
:
.
system
)
perspectiveButton
.
setTitle
(
"3D View"
,
for
:
.
normal
)
perspectiveButton
.
addTarget
(
self
,
action
:
#selector(
onPerspective
)
,
for
:
.
touchUpInside
)
backgroundView
.
addSubview
(
perspectiveButton
)
if
showCurveButton
{
arcCurveButton
=
UIButton
(
type
:
.
system
)
arcCurveButton
!.
setTitle
(
"Show Arcs"
,
for
:
.
normal
)
arcCurveButton
!.
addTarget
(
self
,
action
:
#selector(
onDisplayArcCurve
)
,
for
:
.
touchUpInside
)
backgroundView
.
addSubview
(
arcCurveButton
!
)
}
debugSlider
=
UISlider
(
frame
:
.
zero
)
debugSlider
.
layer
.
zPosition
=
1000
debugSlider
.
minimumValue
=
0
debugSlider
.
maximumValue
=
1
debugSlider
.
addTarget
(
self
,
action
:
#selector(
onSlide
)
,
for
:
.
valueChanged
)
debugSlider
.
isUserInteractionEnabled
=
true
debugSlider
.
value
=
initialProcess
backgroundView
.
addSubview
(
debugSlider
)
panGR
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
#selector(
pan
)
)
panGR
.
delegate
=
self
panGR
.
maximumNumberOfTouches
=
1
addGestureRecognizer
(
panGR
)
pinchGR
=
UIPinchGestureRecognizer
(
target
:
self
,
action
:
#selector(
pinch
)
)
pinchGR
.
delegate
=
self
addGestureRecognizer
(
pinchGR
)
}
required
public
init
?(
coder
aDecoder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
public
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
var
backgroundFrame
=
bounds
backgroundFrame
.
size
.
height
=
72
if
showOnTop
{
backgroundFrame
.
origin
.
y
=
showControls
?
0
:
-
80
}
else
{
backgroundFrame
.
origin
.
y
=
bounds
.
maxY
-
CGFloat
(
showControls
?
72.0
:
-
8.0
)
}
backgroundView
.
frame
=
backgroundFrame
var
sliderFrame
=
bounds
.
insetBy
(
dx
:
10
,
dy
:
0
)
sliderFrame
.
size
.
height
=
44
sliderFrame
.
origin
.
y
=
28
debugSlider
.
frame
=
sliderFrame
perspectiveButton
.
sizeToFit
()
perspectiveButton
.
frame
.
origin
=
CGPoint
(
x
:
bounds
.
maxX
-
perspectiveButton
.
bounds
.
width
-
10
,
y
:
4
)
doneButton
.
sizeToFit
()
doneButton
.
frame
.
origin
=
CGPoint
(
x
:
10
,
y
:
4
)
arcCurveButton
?
.
sizeToFit
()
arcCurveButton
?
.
center
=
CGPoint
(
x
:
center
.
x
,
y
:
doneButton
.
center
.
y
)
}
var
startRotation
:
CGFloat
=
0
@objc
public
func
pan
()
{
if
panGR
.
state
==
.
began
{
startRotation
=
rotate
}
rotate
=
startRotation
+
panGR
.
translation
(
in
:
nil
)
.
x
/
150
if
rotate
>
.
pi
{
rotate
-=
2
*
.
pi
}
else
if
rotate
<
-.
pi
{
rotate
+=
2
*
.
pi
}
delegate
?
.
onPerspectiveChanged
(
translation
:
translation
,
rotate
:
rotate
,
scale
:
scale
)
}
var
startLocation
:
CGPoint
=
.
zero
var
startTranslation
:
CGPoint
=
.
zero
var
startScale
:
CGFloat
=
1
@objc
public
func
pinch
()
{
switch
pinchGR
.
state
{
case
.
began
:
startLocation
=
pinchGR
.
location
(
in
:
nil
)
startTranslation
=
translation
startScale
=
scale
fallthrough
case
.
changed
:
if
pinchGR
.
numberOfTouches
>=
2
{
scale
=
min
(
1
,
max
(
0.2
,
startScale
*
pinchGR
.
scale
))
translation
=
startTranslation
+
pinchGR
.
location
(
in
:
nil
)
-
startLocation
delegate
?
.
onPerspectiveChanged
(
translation
:
translation
,
rotate
:
rotate
,
scale
:
scale
)
}
default
:
break
}
}
@objc
public
func
onDone
()
{
delegate
?
.
onDone
()
}
@objc
public
func
onPerspective
()
{
perspectiveButton
.
isSelected
=
!
perspectiveButton
.
isSelected
delegate
?
.
on3D
(
wants3D
:
perspectiveButton
.
isSelected
)
}
@objc
public
func
onDisplayArcCurve
()
{
arcCurveButton
!.
isSelected
=
!
arcCurveButton
!.
isSelected
delegate
?
.
onDisplayArcCurve
(
wantsCurve
:
arcCurveButton
!.
isSelected
)
}
@objc
public
func
onSlide
()
{
delegate
?
.
onProcessSliderChanged
(
progress
:
debugSlider
.
value
)
}
}
extension
MotionDebugView
:
UIGestureRecognizerDelegate
{
public
override
func
gestureRecognizerShouldBegin
(
_
gestureRecognizer
:
UIGestureRecognizer
)
->
Bool
{
return
perspectiveButton
.
isSelected
}
}
#endif
Sources/MotionController.swift
View file @
936c5b62
...
...
@@ -470,7 +470,7 @@ fileprivate extension MotionController {
/// Prepares the preprocessors.
func
preparePreprocessors
()
{
preprocessors
=
[
IgnoreSubview
Modifier
sPreprocessor
(),
IgnoreSubview
Transition
sPreprocessor
(),
MatchPreprocessor
(),
SourcePreprocessor
(),
CascadePreprocessor
(),
...
...
Sources/MotionPlugin.swift
View file @
936c5b62
...
...
@@ -56,12 +56,12 @@ open class MotionPlugin: NSObject, MotionPreprocessor, MotionAnimator {
To check a view's transitions:
context[view]
context[view, "
modifier
Name"]
context[view, "
transition
Name"]
To set a view's transitions:
context[view] = [("
modifier1", ["parameter1"]), ("modifier
2", [])]
context[view, "
modifier
1"] = ["parameter1", "parameter2"]
context[view] = [("
transition1", ["parameter1"]), ("transition
2", [])]
context[view, "
transition
1"] = ["parameter1", "parameter2"]
*/
open
func
process
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
{}
...
...
Sources/MotionTransition.swift
View file @
936c5b62
...
...
@@ -520,7 +520,7 @@ extension MotionTransition {
that appear differently than the actual view.
In that case, use .useNormalSnapshot or .useSlowRenderSnapshot to disable the optimization.
This
modifier
actually does nothing by itself since .useOptimizedSnapshot is the default.
This
transition
actually does nothing by itself since .useOptimizedSnapshot is the default.
*/
public
static
var
useOptimizedSnapshot
=
MotionTransition
{
$0
.
snapshotType
=
.
optimized
...
...
Sources/Preprocessors/CascadePreprocessor.swift
View file @
936c5b62
...
...
@@ -65,7 +65,7 @@ class CascadePreprocessor: MotionPreprocessor {
weak
var
context
:
MotionContext
!
/**
Processes the
from-views and to-
views.
Processes the
transitionary
views.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
...
...
@@ -84,8 +84,7 @@ class CascadePreprocessor: MotionPreprocessor {
continue
}
var
parentView
=
v
is
UITableView
?
v
.
subviews
.
get
(
0
)
??
v
:
v
let
parentView
=
v
is
UITableView
?
v
.
subviews
.
get
(
0
)
??
v
:
v
let
sortedSubviews
=
parentView
.
subviews
.
sorted
(
by
:
direction
.
comparator
)
let
initialDelay
=
context
[
v
]
!.
delay
...
...
Sources/Preprocessors/DurationPreprocessor.swift
View file @
936c5b62
...
...
@@ -33,7 +33,7 @@ class DurationPreprocessor: MotionPreprocessor {
weak
var
context
:
MotionContext
!
/**
Implementation for processor
.
Processes the transitionary views
.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
...
...
Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift
View file @
936c5b62
...
...
@@ -28,37 +28,54 @@
import
UIKit
class
IgnoreSubview
Modifier
sPreprocessor
:
MotionPreprocessor
{
class
IgnoreSubview
Transition
sPreprocessor
:
MotionPreprocessor
{
/// A reference to a MotionContext.
weak
var
context
:
MotionContext
!
/**
Processes the transitionary views.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
func
process
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
{
process
(
views
:
fromViews
)
process
(
views
:
toViews
)
}
process
(
views
:
fromViews
)
process
(
views
:
toViews
)
}
func
process
(
views
:
[
UIView
])
{
for
view
in
views
{
guard
let
recursive
=
context
[
view
]?
.
ignoreSubviewTransitions
else
{
continue
}
var
parentView
=
view
if
view
is
UITableView
,
let
wrapperView
=
view
.
subviews
.
get
(
0
)
{
parentView
=
wrapperView
}
/**
Process an Array of views for the cascade animation.
- Parameter views: An Array of UIViews.
*/
func
process
(
views
:
[
UIView
])
{
for
v
in
views
{
guard
let
recursive
=
context
[
v
]?
.
ignoreSubviewTransitions
else
{
continue
}
let
parentView
=
v
is
UITableView
?
v
.
subviews
.
get
(
0
)
??
v
:
v
if
recursive
{
cleanSubviewModifiers
(
parentView
)
}
else
{
for
subview
in
parentView
.
subviews
{
context
[
subview
]
=
nil
guard
recursive
else
{
for
subview
in
parentView
.
subviews
{
context
[
subview
]
=
nil
}
continue
}
cleanSubviewTransitions
(
for
:
parentView
)
}
}
}
}
}
private
func
cleanSubviewModifiers
(
_
parentView
:
UIView
)
{
for
view
in
parentView
.
subviews
{
context
[
view
]
=
nil
cleanSubviewModifiers
(
view
)
extension
IgnoreSubviewTransitionsPreprocessor
{
/**
Clears the transition for a given view's subviews.
- Parameter for view: A UIView.
*/
fileprivate
func
cleanSubviewTransitions
(
for
view
:
UIView
)
{
for
v
in
view
.
subviews
{
context
[
v
]
=
nil
cleanSubviewTransitions
(
for
:
v
)
}
}
}
}
Sources/TransitionPreprocessor.swift
View file @
936c5b62
...
...
@@ -188,36 +188,7 @@ class TransitionPreprocessor: MotionPreprocessor {
}
/**
Shifts the transition by a given size.
- Parameter direction: A MotionTransitionType.Direction.
- Parameter isAppearing: A boolean indicating whether it is appearing
or not.
- Parameter size: An optional CGSize.
- Parameter transpose: A boolean indicating to change the `x` point for `y`
and `y` point for `x`.
- Returns: A CGPoint.
*/
func
shift
(
direction
:
MotionTransitionType
.
Direction
,
isAppearing
:
Bool
,
size
:
CGSize
?
=
nil
,
transpose
:
Bool
=
false
)
->
CGPoint
{
let
size
=
size
??
context
.
container
.
bounds
.
size
let
point
:
CGPoint
switch
direction
{
case
.
left
,
.
right
:
point
=
CGPoint
(
x
:
(
.
right
==
direction
)
==
isAppearing
?
-
size
.
width
:
size
.
width
,
y
:
0
)
case
.
up
,
.
down
:
point
=
CGPoint
(
x
:
0
,
y
:
(
.
down
==
direction
)
==
isAppearing
?
-
size
.
height
:
size
.
height
)
}
if
transpose
{
return
CGPoint
(
x
:
point
.
y
,
y
:
point
.
x
)
}
return
point
}
/**
Implementation for processor.
Processes the transitionary views.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
...
...
@@ -376,4 +347,33 @@ class TransitionPreprocessor: MotionPreprocessor {
fatalError
(
"Not implemented"
)
}
}
/**
Shifts the transition by a given size.
- Parameter direction: A MotionTransitionType.Direction.
- Parameter isAppearing: A boolean indicating whether it is appearing
or not.
- Parameter size: An optional CGSize.
- Parameter transpose: A boolean indicating to change the `x` point for `y`
and `y` point for `x`.
- Returns: A CGPoint.
*/
func
shift
(
direction
:
MotionTransitionType
.
Direction
,
isAppearing
:
Bool
,
size
:
CGSize
?
=
nil
,
transpose
:
Bool
=
false
)
->
CGPoint
{
let
size
=
size
??
context
.
container
.
bounds
.
size
let
point
:
CGPoint
switch
direction
{
case
.
left
,
.
right
:
point
=
CGPoint
(
x
:
(
.
right
==
direction
)
==
isAppearing
?
-
size
.
width
:
size
.
width
,
y
:
0
)
case
.
up
,
.
down
:
point
=
CGPoint
(
x
:
0
,
y
:
(
.
down
==
direction
)
==
isAppearing
?
-
size
.
height
:
size
.
height
)
}
if
transpose
{
return
CGPoint
(
x
:
point
.
y
,
y
:
point
.
x
)
}
return
point
}
}
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