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
ce1eaaed
Commit
ce1eaaed
authored
Oct 10, 2017
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updates for iOS 11 snapshots container changes
parent
0c670f8a
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
128 additions
and
69 deletions
+128
-69
Sources/Extensions/Motion+CALayer.swift
+17
-0
Sources/Extensions/Motion+UIView.swift
+58
-8
Sources/Motion.swift
+13
-13
Sources/MotionContext.swift
+40
-41
Sources/MotionCoordinateSpace.swift
+0
-1
Sources/MotionIndependentController.swift
+0
-1
Sources/MotionTransition.swift
+0
-5
No files found.
Sources/Extensions/Motion+CALayer.swift
View file @
ce1eaaed
...
...
@@ -39,6 +39,23 @@ internal extension CALayer {
return
(
$0
,
self
.
animation
(
forKey
:
$0
)
!.
copy
()
as!
CAAnimation
)
}
}
/**
Concats transforms and returns the result.
- Parameters layer: A CALayer.
- Returns: A CATransform3D.
*/
func
flatTransformTo
(
layer
:
CALayer
)
->
CATransform3D
{
var
l
=
layer
var
t
=
l
.
transform
while
let
sl
=
l
.
superlayer
,
self
!=
sl
{
t
=
CATransform3DConcat
(
sl
.
transform
,
t
)
l
=
sl
}
return
t
}
}
public
extension
CALayer
{
...
...
Sources/Extensions/Motion+UIView.swift
View file @
ce1eaaed
...
...
@@ -34,6 +34,9 @@ fileprivate struct AssociatedInstance {
/// A boolean indicating whether Motion is enabled.
fileprivate
var
isEnabled
:
Bool
/// A boolean indicating whether Motion is enabled for subviews.
fileprivate
var
isEnabledForSubviews
:
Bool
/// An optional reference to the motion identifier.
fileprivate
var
identifier
:
String
?
...
...
@@ -52,7 +55,7 @@ fileprivate extension UIView {
fileprivate
var
associatedInstance
:
AssociatedInstance
{
get
{
return
AssociatedObject
.
get
(
base
:
self
,
key
:
&
AssociatedInstanceKey
)
{
return
AssociatedInstance
(
isEnabled
:
true
,
identifier
:
nil
,
animations
:
nil
,
transitions
:
nil
,
alpha
:
1
)
return
AssociatedInstance
(
isEnabled
:
true
,
i
sEnabledForSubviews
:
true
,
i
dentifier
:
nil
,
animations
:
nil
,
transitions
:
nil
,
alpha
:
1
)
}
}
set
(
value
)
{
...
...
@@ -73,6 +76,17 @@ public extension UIView {
}
}
/// A boolean that indicates whether motion is enabled.
@IBInspectable
var
isMotionEnabledForSubviews
:
Bool
{
get
{
return
associatedInstance
.
isEnabledForSubviews
}
set
(
value
)
{
associatedInstance
.
isEnabledForSubviews
=
value
}
}
/// An identifier value used to connect views across UIViewControllers.
@IBInspectable
var
motionIdentifier
:
String
?
{
...
...
@@ -195,6 +209,25 @@ internal extension UIView {
}
}
internal
class
SnapshotWrapperView
:
UIView
{
let
contentView
:
UIView
init
(
contentView
:
UIView
)
{
self
.
contentView
=
contentView
super
.
init
(
frame
:
contentView
.
frame
)
addSubview
(
contentView
)
}
required
init
?(
coder
aDecoder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
contentView
.
bounds
.
size
=
bounds
.
size
contentView
.
center
=
bounds
.
center
}
}
internal
extension
UIView
{
/// Retrieves a single Array of UIViews that are in the view hierarchy.
var
flattenedViewHierarchy
:
[
UIView
]
{
...
...
@@ -202,11 +235,15 @@ internal extension UIView {
return
[]
}
if
#available(iOS 9.0, *)
{
return
isHidden
&&
(
superview
is
UICollectionView
||
superview
is
UIStackView
||
self
is
UITableViewCell
)
?
[]
:
([
self
]
+
subviews
.
flatMap
{
$0
.
flattenedViewHierarchy
})
if
#available(iOS 9.0, *)
,
isHidden
&&
(
superview
is
UICollectionView
||
superview
is
UIStackView
||
self
is
UITableViewCell
)
{
return
[]
}
else
if
isHidden
&&
(
superview
is
UICollectionView
||
self
is
UITableViewCell
)
{
return
[]
}
else
if
isMotionEnabledForSubviews
{
return
[
self
]
+
subviews
.
flatMap
{
$0
.
flattenedViewHierarchy
}
}
else
{
return
[
self
]
}
return
isHidden
&&
(
superview
is
UICollectionView
||
self
is
UITableViewCell
)
?
[]
:
([
self
]
+
subviews
.
flatMap
{
$0
.
flattenedViewHierarchy
})
}
/**
...
...
@@ -250,8 +287,21 @@ internal extension UIView {
let
imageView
=
UIImageView
(
image
:
image
)
imageView
.
frame
=
bounds
let
snapshotView
=
UIView
(
frame
:
bounds
)
snapshotView
.
addSubview
(
imageView
)
return
snapshotView
return
SnapshotWrapperView
(
contentView
:
imageView
)
}
/**
Returns a snapshot of the view itself.
- Returns: An optional UIView.
*/
func
snapshotView
()
->
UIView
?
{
let
snapshot
=
snapshotView
(
afterScreenUpdates
:
true
)
if
#available(iOS 11.0, *)
,
let
oldSnapshot
=
snapshot
{
/// iOS 11 no longer contains a container view.
return
SnapshotWrapperView
(
contentView
:
oldSnapshot
)
}
return
snapshot
}
}
Sources/Motion.swift
View file @
ce1eaaed
...
...
@@ -702,15 +702,15 @@ extension Motion: UIViewControllerTransitioningDelegate {
}
public
func
animationController
(
forPresented
presented
:
UIViewController
,
presenting
:
UIViewController
,
source
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
self
.
isPresenting
=
true
self
.
fromViewController
=
fromViewController
??
presenting
self
.
toViewController
=
toViewController
??
presented
isPresenting
=
true
fromViewController
=
fromViewController
??
presenting
toViewController
=
toViewController
??
presented
return
self
}
public
func
animationController
(
forDismissed
dismissed
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
self
.
isPresenting
=
false
self
.
fromViewController
=
fromViewController
??
dismissed
isPresenting
=
false
fromViewController
=
fromViewController
??
dismissed
return
self
}
...
...
@@ -734,10 +734,10 @@ extension Motion: UIViewControllerInteractiveTransitioning {
extension
Motion
:
UINavigationControllerDelegate
{
public
func
navigationController
(
_
navigationController
:
UINavigationController
,
animationControllerFor
operation
:
UINavigationControllerOperation
,
from
fromVC
:
UIViewController
,
to
toVC
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
self
.
isPresenting
=
.
push
==
operation
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
toViewController
=
toViewController
??
toVC
self
.
isNavigationController
=
true
isPresenting
=
.
push
==
operation
fromViewController
=
fromViewController
??
fromVC
toViewController
=
toViewController
??
toVC
isNavigationController
=
true
return
self
}
...
...
@@ -761,10 +761,10 @@ extension Motion: UITabBarControllerDelegate {
let
fromVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
fromVC
)
!
let
toVCIndex
=
tabBarController
.
childViewControllers
.
index
(
of
:
toVC
)
!
self
.
isPresenting
=
toVCIndex
>
fromVCIndex
self
.
fromViewController
=
fromViewController
??
fromVC
self
.
toViewController
=
toViewController
??
toVC
self
.
isTabBarController
=
true
isPresenting
=
toVCIndex
>
fromVCIndex
fromViewController
=
fromViewController
??
fromVC
toViewController
=
toViewController
??
toVC
isTabBarController
=
true
return
self
}
...
...
Sources/MotionContext.swift
View file @
ce1eaaed
...
...
@@ -163,8 +163,8 @@ public extension MotionContext {
- Returns: A UIView.
*/
func
snapshotView
(
for
view
:
UIView
)
->
UIView
{
if
let
v
=
viewToSnapshot
[
view
]
{
return
v
if
let
snapshot
=
viewToSnapshot
[
view
]
{
return
snapshot
}
var
containerView
=
container
...
...
@@ -174,27 +174,27 @@ public extension MotionContext {
case
.
local
:
containerView
=
view
while
containerView
!=
container
,
nil
==
viewToSnapshot
[
containerView
]
,
let
superview
=
containerView
.
superview
{
while
containerView
!=
container
,
viewToSnapshot
[
containerView
]
==
nil
,
let
superview
=
containerView
.
superview
{
containerView
=
superview
}
if
let
snapshot
=
viewToSnapshot
[
containerView
]
{
containerView
=
snapshot
}
case
.
sameParent
:
containerView
=
view
.
superview
!
if
let
visualEffectView
=
containerView
as?
UIVisualEffectView
{
containerView
=
visualEffectView
.
contentView
}
case
.
global
:
break
}
unhide
(
view
:
view
)
//
Capture a snapshot without the alpha & cornerRadius value
s.
//
/ Capture a snapshot without alpha & cornerRadiu
s.
let
oldCornerRadius
=
view
.
layer
.
cornerRadius
view
.
layer
.
cornerRadius
=
0
let
oldAlpha
=
view
.
alpha
view
.
layer
.
cornerRadius
=
0
view
.
alpha
=
1
let
snapshot
:
UIView
...
...
@@ -202,59 +202,57 @@ public extension MotionContext {
switch
snapshotType
{
case
.
normal
:
snapshot
=
view
.
snapshotView
(
afterScreenUpdates
:
true
)
!
snapshot
=
view
.
snapshotView
(
)
??
UIView
()
case
.
layerRender
:
snapshot
=
view
.
slowSnapshotView
()
case
.
noSnapshot
:
if
nil
==
superviewToNoSnapshotSubviewMap
[
view
.
superview
!
]
{
if
view
.
superview
!=
container
{
if
superviewToNoSnapshotSubviewMap
[
view
.
superview
!
]
==
nil
{
superviewToNoSnapshotSubviewMap
[
view
.
superview
!
]
=
[]
}
superviewToNoSnapshotSubviewMap
[
view
.
superview
!
]
!.
append
((
view
.
superview
!.
subviews
.
index
(
of
:
view
)
!
,
view
))
}
snapshot
=
view
case
.
optimized
:
#if os(tvOS)
snapshot
=
view
.
snapshotView
(
afterScreenUpdates
:
true
)
!
#else
if
#available(iOS 9.0, *)
,
let
stackView
=
view
as?
UIStackView
{
snapshot
=
stackView
.
slowSnapshotView
()
}
else
if
let
imageView
=
view
as?
UIImageView
,
view
.
subviews
.
isEmpty
{
let
contentView
=
UIImageView
(
image
:
imageView
.
image
)
contentView
.
frame
=
imageView
.
bounds
contentView
.
contentMode
=
imageView
.
contentMode
contentView
.
tintColor
=
imageView
.
tintColor
contentView
.
backgroundColor
=
imageView
.
backgroundColor
let
snapShotView
=
UIView
()
snapShotView
.
addSubview
(
contentView
)
snapshot
=
snapShotView
}
else
if
let
barView
=
view
as?
UINavigationBar
,
barView
.
isTranslucent
{
let
newBarView
=
UINavigationBar
(
frame
:
barView
.
frame
)
}
else
if
let
navigationBar
=
view
as?
UINavigationBar
,
navigationBar
.
isTranslucent
{
let
newNavigationBar
=
UINavigationBar
(
frame
:
navigationBar
.
frame
)
newNavigationBar
.
barStyle
=
navigationBar
.
barStyle
newNavigationBar
.
tintColor
=
navigationBar
.
tintColor
newNavigationBar
.
barTintColor
=
navigationBar
.
barTintColor
newNavigationBar
.
clipsToBounds
=
false
newBarView
.
barStyle
=
barView
.
barStyle
newBarView
.
tintColor
=
barView
.
tintColor
newBarView
.
barTintColor
=
barView
.
barTintColor
newBarView
.
clipsToBounds
=
false
// Take a snapshot without the background.
navigationBar
.
layer
.
sublayers
!
[
0
]
.
opacity
=
0
let
realSnapshot
=
navigationBar
.
snapshotView
(
afterScreenUpdates
:
true
)
!
navigationBar
.
layer
.
sublayers
!
[
0
]
.
opacity
=
1
newNavigationBar
.
addSubview
(
realSnapshot
)
snapshot
=
newNavigationBar
// take a snapshot without the background
barView
.
layer
.
sublayers
!
[
0
]
.
opacity
=
0
let
realSnapshot
=
barView
.
snapshotView
(
afterScreenUpdates
:
true
)
!
barView
.
layer
.
sublayers
!
[
0
]
.
opacity
=
1
newBarView
.
addSubview
(
realSnapshot
)
snapshot
=
newBarView
}
else
if
let
effectView
=
view
as?
UIVisualEffectView
{
snapshot
=
UIVisualEffectView
(
effect
:
effectView
.
effect
)
snapshot
.
frame
=
effectView
.
bounds
}
else
{
snapshot
=
view
.
snapshotView
(
afterScreenUpdates
:
true
)
!
snapshot
=
view
.
snapshotView
(
)
??
UIView
()
}
#endif
}
...
...
@@ -268,18 +266,21 @@ public extension MotionContext {
view
.
layer
.
cornerRadius
=
oldCornerRadius
view
.
alpha
=
oldAlpha
if
.
noSnapshot
!=
snapshotType
{
snapshot
.
layer
.
allowsGroupOpacity
=
false
snapshot
.
layer
.
anchorPoint
=
view
.
layer
.
anchorPoint
snapshot
.
layer
.
position
=
containerView
.
convert
(
view
.
layer
.
position
,
from
:
view
.
superview
!
)
snapshot
.
layer
.
transform
=
containerView
.
layer
.
flatTransformTo
(
layer
:
view
.
layer
)
snapshot
.
layer
.
bounds
=
view
.
layer
.
bounds
snapshot
.
motionIdentifier
=
view
.
motionIdentifier
if
snapshotType
!=
.
noSnapshot
{
if
!
(
view
is
UINavigationBar
),
let
contentView
=
snapshot
.
subviews
.
get
(
0
)
{
/**
The snapshot's contentView must have the cornerRadius value,
since the snapshot might not have maskToBounds set
*/
// the Snapshot's contentView must have hold the cornerRadius value,
// since the snapshot might not have maskToBounds set
contentView
.
layer
.
cornerRadius
=
view
.
layer
.
cornerRadius
contentView
.
layer
.
masksToBounds
=
true
}
snapshot
.
layer
.
allowsGroupOpacity
=
false
snapshot
.
layer
.
cornerRadius
=
view
.
layer
.
cornerRadius
snapshot
.
layer
.
zPosition
=
view
.
layer
.
zPosition
snapshot
.
layer
.
opacity
=
view
.
layer
.
opacity
...
...
@@ -288,7 +289,6 @@ public extension MotionContext {
snapshot
.
layer
.
masksToBounds
=
view
.
layer
.
masksToBounds
snapshot
.
layer
.
borderColor
=
view
.
layer
.
borderColor
snapshot
.
layer
.
borderWidth
=
view
.
layer
.
borderWidth
snapshot
.
layer
.
transform
=
view
.
layer
.
transform
snapshot
.
layer
.
contentsRect
=
view
.
layer
.
contentsRect
snapshot
.
layer
.
contentsScale
=
view
.
layer
.
contentsScale
...
...
@@ -299,18 +299,16 @@ public extension MotionContext {
snapshot
.
layer
.
shadowOffset
=
view
.
layer
.
shadowOffset
snapshot
.
layer
.
shadowPath
=
view
.
layer
.
shadowPath
}
}
snapshot
.
frame
=
containerView
.
convert
(
view
.
bounds
,
from
:
view
)
snapshot
.
motionIdentifier
=
view
.
motionIdentifier
hide
(
view
:
view
)
}
if
let
pairedView
=
transitionPairedView
(
for
:
view
),
let
pairedSnapshot
=
viewToSnapshot
[
pairedView
]
{
let
siblingViews
=
pairedView
.
superview
!.
subviews
let
nextSiblings
=
siblingViews
[
siblingViews
.
index
(
of
:
pairedView
)
!
+
1
..<
siblingViews
.
count
]
let
nextSiblings
=
siblingViews
[
siblingViews
.
index
(
of
:
pairedView
)
!
+
1
..<
siblingViews
.
count
]
containerView
.
addSubview
(
pairedSnapshot
)
containerView
.
addSubview
(
snapshot
)
for
subview
in
pairedView
.
subviews
{
insertGlobalViewTree
(
view
:
subview
)
...
...
@@ -319,10 +317,11 @@ public extension MotionContext {
for
sibling
in
nextSiblings
{
insertGlobalViewTree
(
view
:
sibling
)
}
}
else
{
containerView
.
addSubview
(
snapshot
)
}
containerView
.
addSubview
(
snapshot
)
viewToSnapshot
[
view
]
=
snapshot
return
snapshot
...
...
Sources/MotionCoordinateSpace.swift
View file @
ce1eaaed
...
...
@@ -31,5 +31,4 @@ import UIKit
public
enum
MotionCoordinateSpace
{
case
global
case
local
case
sameParent
}
Sources/MotionIndependentController.swift
View file @
ce1eaaed
...
...
@@ -61,7 +61,6 @@ fileprivate extension MotionIndependentController {
- PArameter toViews: An Array of UIViews.
*/
func
prepareContext
(
fromViews
:
[
UIView
],
toViews
:
[
UIView
])
{
context
.
defaultCoordinateSpace
=
.
sameParent
context
.
set
(
fromViews
:
fromViews
,
toViews
:
toViews
)
processContext
()
}
...
...
Sources/MotionTransition.swift
View file @
ce1eaaed
...
...
@@ -515,11 +515,6 @@ public extension MotionTransition {
$0
.
coordinateSpace
=
.
global
}
/// Use same parent coordinate space.
static
var
useSameParentCoordinateSpace
=
MotionTransition
{
$0
.
coordinateSpace
=
.
sameParent
}
/// Ignore all motion transition attributes for a view's direct subviews.
static
var
ignoreSubviewTransitions
:
MotionTransition
=
.
ignoreSubviewTransitions
()
...
...
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