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
542797fb
Unverified
Commit
542797fb
authored
Dec 24, 2016
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
development: renamed Pulse to MotionPulse and added MotionSpring
parent
23bd140d
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
582 additions
and
590 deletions
+582
-590
Material.xcodeproj/project.pbxproj
+4
-0
Sources/iOS/Button.swift
+2
-2
Sources/iOS/CollectionReusableView.swift
+2
-2
Sources/iOS/CollectionViewCell.swift
+2
-2
Sources/iOS/FABMenu.swift
+43
-3
Sources/iOS/Menu.swift
+9
-575
Sources/iOS/MotionPulse.swift
+6
-2
Sources/iOS/MotionSpring.swift
+510
-0
Sources/iOS/PulseView.swift
+2
-2
Sources/iOS/TableViewCell.swift
+2
-2
No files found.
Material.xcodeproj/project.pbxproj
View file @
542797fb
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
objects
=
{
objects
=
{
/* Begin PBXBuildFile section */
/* Begin PBXBuildFile section */
961730361E0E156400A9A297
/* MotionSpring.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
961730351E0E156400A9A297
/* MotionSpring.swift */
;
};
9617B07D1DFCA8CF00410F8F
/* Application.swift in Headers */
=
{
isa
=
PBXBuildFile
;
fileRef
=
961E6BDE1DDA2A95004E6C93
/* Application.swift */
;
settings
=
{
ATTRIBUTES
=
(
Public
,
);
};
};
9617B07D1DFCA8CF00410F8F
/* Application.swift in Headers */
=
{
isa
=
PBXBuildFile
;
fileRef
=
961E6BDE1DDA2A95004E6C93
/* Application.swift */
;
settings
=
{
ATTRIBUTES
=
(
Public
,
);
};
};
9617B07E1DFCA8CF00410F8F
/* Card.swift in Headers */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96BCB75D1CB40DC500C806FE
/* Card.swift */
;
settings
=
{
ATTRIBUTES
=
(
Public
,
);
};
};
9617B07E1DFCA8CF00410F8F
/* Card.swift in Headers */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96BCB75D1CB40DC500C806FE
/* Card.swift */
;
settings
=
{
ATTRIBUTES
=
(
Public
,
);
};
};
9617B07F1DFCA8CF00410F8F
/* ImageCard.swift in Headers */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96BCB7621CB40DC500C806FE
/* ImageCard.swift */
;
settings
=
{
ATTRIBUTES
=
(
Public
,
);
};
};
9617B07F1DFCA8CF00410F8F
/* ImageCard.swift in Headers */
=
{
isa
=
PBXBuildFile
;
fileRef
=
96BCB7621CB40DC500C806FE
/* ImageCard.swift */
;
settings
=
{
ATTRIBUTES
=
(
Public
,
);
};
};
...
@@ -228,6 +229,7 @@
...
@@ -228,6 +229,7 @@
/* Begin PBXFileReference section */
/* Begin PBXFileReference section */
961276621DCD8B1800A7D920
/* CharacterAttribute.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CharacterAttribute.swift
;
sourceTree
=
"<group>"
;
};
961276621DCD8B1800A7D920
/* CharacterAttribute.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CharacterAttribute.swift
;
sourceTree
=
"<group>"
;
};
961730351E0E156400A9A297
/* MotionSpring.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MotionSpring.swift
;
sourceTree
=
"<group>"
;
};
961DED451DCC40C500F425B6
/* Editor.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Editor.swift
;
sourceTree
=
"<group>"
;
};
961DED451DCC40C500F425B6
/* Editor.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Editor.swift
;
sourceTree
=
"<group>"
;
};
961DED4A1DCC546100F425B6
/* EditorController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
EditorController.swift
;
sourceTree
=
"<group>"
;
};
961DED4A1DCC546100F425B6
/* EditorController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
EditorController.swift
;
sourceTree
=
"<group>"
;
};
961E6BDE1DDA2A95004E6C93
/* Application.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Application.swift
;
sourceTree
=
"<group>"
;
};
961E6BDE1DDA2A95004E6C93
/* Application.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Application.swift
;
sourceTree
=
"<group>"
;
};
...
@@ -793,6 +795,7 @@
...
@@ -793,6 +795,7 @@
96BCB77E1CB40DC500C806FE
/* MotionKeyframe.swift */
,
96BCB77E1CB40DC500C806FE
/* MotionKeyframe.swift */
,
96E3C39D1D3A1D0C0086A024
/* MotionBasic.swift */
,
96E3C39D1D3A1D0C0086A024
/* MotionBasic.swift */
,
96BCB7821CB40DC500C806FE
/* MotionPulse.swift */
,
96BCB7821CB40DC500C806FE
/* MotionPulse.swift */
,
961730351E0E156400A9A297
/* MotionSpring.swift */
,
);
);
name
=
Motion
;
name
=
Motion
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -1161,6 +1164,7 @@
...
@@ -1161,6 +1164,7 @@
965E81031DD4D5C800D61E4B
/* CollectionView.swift in Sources */
,
965E81031DD4D5C800D61E4B
/* CollectionView.swift in Sources */
,
965E81041DD4D5C800D61E4B
/* CollectionViewCell.swift in Sources */
,
965E81041DD4D5C800D61E4B
/* CollectionViewCell.swift in Sources */
,
965E81071DD4D5C800D61E4B
/* CollectionViewLayout.swift in Sources */
,
965E81071DD4D5C800D61E4B
/* CollectionViewLayout.swift in Sources */
,
961730361E0E156400A9A297
/* MotionSpring.swift in Sources */
,
965E81081DD4D5C800D61E4B
/* CollectionReusableView.swift in Sources */
,
965E81081DD4D5C800D61E4B
/* CollectionReusableView.swift in Sources */
,
965E81091DD4D5C800D61E4B
/* DataSourceItem.swift in Sources */
,
965E81091DD4D5C800D61E4B
/* DataSourceItem.swift in Sources */
,
965E810A1DD4D5C800D61E4B
/* Font.swift in Sources */
,
965E810A1DD4D5C800D61E4B
/* Font.swift in Sources */
,
...
...
Sources/iOS/Button.swift
View file @
542797fb
...
@@ -40,7 +40,7 @@ open class Button: UIButton, Pulseable {
...
@@ -40,7 +40,7 @@ open class Button: UIButton, Pulseable {
open
let
visualLayer
=
CAShapeLayer
()
open
let
visualLayer
=
CAShapeLayer
()
/// A Pulse reference.
/// A Pulse reference.
fileprivate
var
pulse
:
Pulse
!
fileprivate
var
pulse
:
Motion
Pulse
!
/// PulseAnimation value.
/// PulseAnimation value.
open
var
pulseAnimation
:
PulseAnimation
{
open
var
pulseAnimation
:
PulseAnimation
{
...
@@ -261,7 +261,7 @@ extension Button {
...
@@ -261,7 +261,7 @@ extension Button {
/// Prepares the pulse motion.
/// Prepares the pulse motion.
fileprivate
func
preparePulse
()
{
fileprivate
func
preparePulse
()
{
pulse
=
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
pulse
=
Motion
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
}
}
/**
/**
...
...
Sources/iOS/CollectionReusableView.swift
View file @
542797fb
...
@@ -41,7 +41,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable {
...
@@ -41,7 +41,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable {
open
let
visualLayer
=
CAShapeLayer
()
open
let
visualLayer
=
CAShapeLayer
()
/// A Pulse reference.
/// A Pulse reference.
fileprivate
var
pulse
:
Pulse
!
fileprivate
var
pulse
:
Motion
Pulse
!
/// PulseAnimation value.
/// PulseAnimation value.
open
var
pulseAnimation
:
PulseAnimation
{
open
var
pulseAnimation
:
PulseAnimation
{
...
@@ -295,7 +295,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable {
...
@@ -295,7 +295,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable {
extension
CollectionReusableView
{
extension
CollectionReusableView
{
/// Prepares the pulse motion.
/// Prepares the pulse motion.
fileprivate
func
preparePulse
()
{
fileprivate
func
preparePulse
()
{
pulse
=
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
pulse
=
Motion
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
pulseAnimation
=
.
none
pulseAnimation
=
.
none
}
}
...
...
Sources/iOS/CollectionViewCell.swift
View file @
542797fb
...
@@ -41,7 +41,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable {
...
@@ -41,7 +41,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable {
open
let
visualLayer
=
CAShapeLayer
()
open
let
visualLayer
=
CAShapeLayer
()
/// A Pulse reference.
/// A Pulse reference.
fileprivate
var
pulse
:
Pulse
!
fileprivate
var
pulse
:
Motion
Pulse
!
/// PulseAnimation value.
/// PulseAnimation value.
open
var
pulseAnimation
:
PulseAnimation
{
open
var
pulseAnimation
:
PulseAnimation
{
...
@@ -256,7 +256,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable {
...
@@ -256,7 +256,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable {
extension
CollectionViewCell
{
extension
CollectionViewCell
{
/// Prepares the pulse motion.
/// Prepares the pulse motion.
fileprivate
func
preparePulse
()
{
fileprivate
func
preparePulse
()
{
pulse
=
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
pulse
=
Motion
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
}
}
/// Prepares the visualLayer property.
/// Prepares the visualLayer property.
...
...
Sources/iOS/FABMenu.swift
View file @
542797fb
...
@@ -30,8 +30,16 @@
...
@@ -30,8 +30,16 @@
import
UIKit
import
UIKit
@objc(FABMenuDirection)
public
enum
FABMenuDirection
:
Int
{
case
up
case
down
case
left
case
right
}
@objc(FABMenuDelegate)
@objc(FABMenuDelegate)
public
protocol
FABMenuDelegate
:
MenuDelegate
{
public
protocol
FABMenuDelegate
{
/**
/**
Gets called when the user taps while the menu is opened.
Gets called when the user taps while the menu is opened.
- Parameter menu: A FABMenu.
- Parameter menu: A FABMenu.
...
@@ -46,6 +54,16 @@ public protocol FABMenuDelegate: MenuDelegate {
...
@@ -46,6 +54,16 @@ public protocol FABMenuDelegate: MenuDelegate {
@objc(FABMenu)
@objc(FABMenu)
open
class
FABMenu
:
Menu
{
open
class
FABMenu
:
Menu
{
/// An optional delegation handler.
open
weak
var
delegate
:
FABMenuDelegate
?
/// The direction in which the animation opens the menu.
open
var
direction
=
SpringDirection
.
up
{
didSet
{
layoutSubviews
()
}
}
/// A reference to the MenuItems
/// A reference to the MenuItems
open
var
buttons
:
[
MenuItem
]
{
open
var
buttons
:
[
MenuItem
]
{
get
{
get
{
...
@@ -55,8 +73,30 @@ open class FABMenu: Menu {
...
@@ -55,8 +73,30 @@ open class FABMenu: Menu {
views
=
value
views
=
value
}
}
}
}
}
extension
FABMenu
{
/**
Handles the hit test for the Menu and views outside of the Menu bounds.
- Parameter _ point: A CGPoint.
- Parameter with event: An optional UIEvent.
- Returns: An optional UIView.
*/
open
override
func
hitTest
(
_
point
:
CGPoint
,
with
event
:
UIEvent
?)
->
UIView
?
{
guard
isOpened
,
isEnabled
else
{
return
super
.
hitTest
(
point
,
with
:
event
)
}
for
v
in
subviews
{
let
p
=
v
.
convert
(
point
,
from
:
self
)
if
v
.
bounds
.
contains
(
p
)
{
delegate
?
.
fabMenu
?(
fabMenu
:
self
,
tappedAt
:
point
,
isOutside
:
false
)
return
v
.
hitTest
(
p
,
with
:
event
)
}
}
delegate
?
.
fabMenu
?(
fabMenu
:
self
,
tappedAt
:
point
,
isOutside
:
true
)
open
override
func
prepare
()
{
return
self
.
hitTest
(
point
,
with
:
event
)
super
.
prepare
()
}
}
}
}
Sources/iOS/Menu.swift
View file @
542797fb
...
@@ -30,584 +30,18 @@
...
@@ -30,584 +30,18 @@
import
UIKit
import
UIKit
@objc(MenuDirection)
@objc(menu)
public
enum
MenuDirection
:
Int
{
open
class
Menu
:
View
,
Springable
{
case
up
internal
let
spring
=
Spring
()
case
down
case
left
case
right
}
@objc(MenuDelegate)
public
protocol
MenuDelegate
{
/**
Gets called when the user taps while the menu is opened.
- Parameter menu: A Menu.
- Parameter tappedAt point: A CGPoint.
- Parameter isOutside: A boolean indicating whether the tap
was outside the menu button area.
*/
@objc
optional
func
menu
(
menu
:
Menu
,
tappedAt
point
:
CGPoint
,
isOutside
:
Bool
)
}
open
class
Menu
:
View
{
/// A Boolean that indicates if the menu is open or not.
open
internal(set)
var
isOpened
=
false
/// Enables the animations for the Menu.
open
internal(set)
var
isEnabled
=
true
/// A preset wrapper around interimSpace.
open
var
interimSpacePreset
=
InterimSpacePreset
.
none
{
didSet
{
interimSpace
=
InterimSpacePresetToValue
(
preset
:
interimSpacePreset
)
}
}
/// The space between views.
open
var
interimSpace
:
InterimSpace
=
0
{
didSet
{
layoutSubviews
()
}
}
/// The direction in which the animation opens the menu.
open
var
direction
=
MenuDirection
.
up
{
didSet
{
layoutSubviews
()
}
}
/// A delegation reference.
open
weak
var
delegate
:
MenuDelegate
?
/// An Array of UIViews.
open
var
views
=
[
UIView
]()
{
didSet
{
for
v
in
oldValue
{
v
.
removeFromSuperview
()
}
for
v
in
views
{
addSubview
(
v
)
}
layoutSubviews
()
}
}
/// An Optional base view size.
open
var
baseSize
=
CGSize
(
width
:
48
,
height
:
48
)
/// Size of views, not including the first view.
open
var
itemSize
=
CGSize
(
width
:
48
,
height
:
48
)
open
override
func
hitTest
(
_
point
:
CGPoint
,
with
event
:
UIEvent
?)
->
UIView
?
{
guard
isOpened
,
isEnabled
else
{
return
super
.
hitTest
(
point
,
with
:
event
)
}
for
v
in
subviews
{
let
p
=
v
.
convert
(
point
,
from
:
self
)
if
v
.
bounds
.
contains
(
p
)
{
delegate
?
.
menu
?(
menu
:
self
,
tappedAt
:
point
,
isOutside
:
false
)
return
v
.
hitTest
(
p
,
with
:
event
)
}
}
delegate
?
.
menu
?(
menu
:
self
,
tappedAt
:
point
,
isOutside
:
true
)
return
self
.
hitTest
(
point
,
with
:
event
)
}
/**
Prepares the view instance when intialized. When subclassing,
it is recommended to override the prepare method
to initialize property values and other setup operations.
The super.prepare method should always be called immediately
when subclassing.
*/
open
override
func
prepare
()
{
super
.
prepare
()
backgroundColor
=
nil
interimSpacePreset
=
.
interimSpace6
}
open
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
reload
()
}
/// Reload the view layout.
open
func
reload
()
{
isOpened
=
false
guard
let
base
=
views
.
first
else
{
return
}
base
.
frame
.
size
=
baseSize
base
.
zPosition
=
10000
for
i
in
1
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
alpha
=
0
v
.
isHidden
=
true
v
.
frame
.
size
=
itemSize
v
.
x
=
base
.
x
+
(
baseSize
.
width
-
itemSize
.
width
)
/
2
v
.
y
=
base
.
y
+
(
baseSize
.
height
-
itemSize
.
height
)
/
2
v
.
zPosition
=
CGFloat
(
10000
-
views
.
count
-
i
)
}
}
/// Disable the Menu if views exist.
fileprivate
func
disable
()
{
guard
0
<
views
.
count
else
{
return
}
isEnabled
=
false
}
/**
Enable the Menu if the last view is equal to the passed in view.
- Parameter view: UIView that is passed in to compare.
*/
fileprivate
func
enable
(
view
:
UIView
)
{
guard
view
==
views
.
last
else
{
return
}
isEnabled
=
true
}
}
extension
Menu
{
/**
Open the Menu component with animation options.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
open
func
open
(
duration
:
TimeInterval
=
0.15
,
delay
:
TimeInterval
=
0
,
usingSpringWithDamping
:
CGFloat
=
0.5
,
initialSpringVelocity
:
CGFloat
=
0
,
options
:
UIViewAnimationOptions
=
[],
animations
:
((
UIView
)
->
Void
)?
=
nil
,
completion
:
((
UIView
)
->
Void
)?
=
nil
)
{
if
isEnabled
{
disable
()
switch
direction
{
case
.
up
:
openUpAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
down
:
openDownAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
left
:
openLeftAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
right
:
openRightAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
}
}
}
/**
Close the Menu component with animation options.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
open
func
close
(
duration
:
TimeInterval
=
0.15
,
delay
:
TimeInterval
=
0
,
usingSpringWithDamping
:
CGFloat
=
0.5
,
initialSpringVelocity
:
CGFloat
=
0
,
options
:
UIViewAnimationOptions
=
[],
animations
:
((
UIView
)
->
Void
)?
=
nil
,
completion
:
((
UIView
)
->
Void
)?
=
nil
)
{
if
isEnabled
{
disable
()
switch
direction
{
case
.
up
:
closeUpAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
down
:
closeDownAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
left
:
closeLeftAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
right
:
closeRightAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
}
}
}
}
extension
Menu
{
/**
Open the Menu component with animation options in the Up direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openUpAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
for
i
in
1
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
weak
self
,
base
=
base
,
v
=
v
]
in
guard
let
s
=
self
else
{
return
}
v
.
alpha
=
1
v
.
y
=
base
.
y
-
CGFloat
(
i
)
*
s
.
itemSize
.
height
-
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
guard
let
s
=
self
else
{
return
}
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
true
}
completion
?(
v
)
}
}
}
/**
Close the Menu component with animation options in the Up direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeUpAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
for
i
in
1
..<
views
.
count
{
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
base
=
base
,
v
=
views
[
i
]]
in
v
.
alpha
=
0
v
.
y
=
base
.
y
animations
?(
v
)
})
{
[
weak
self
,
v
=
views
[
i
]]
_
in
guard
let
s
=
self
else
{
return
}
v
.
isHidden
=
true
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
false
}
completion
?(
v
)
}
}
}
/**
Open the Menu component with animation options in the Down direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openDownAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
let
h
=
baseSize
.
height
open
var
views
:
[
UIView
]
{
get
{
for
i
in
1
..<
views
.
count
{
return
spring
.
views
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
weak
self
,
base
=
base
,
v
=
v
]
in
guard
let
s
=
self
else
{
return
}
}
set
(
value
)
{
v
.
alpha
=
1
spring
.
views
=
value
v
.
y
=
base
.
y
+
h
+
CGFloat
(
i
-
1
)
*
s
.
itemSize
.
height
+
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
guard
let
s
=
self
else
{
return
}
}
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
true
}
completion
?(
v
)
}
}
}
/**
Close the Menu component with animation options in the Down direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeDownAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
let
h
=
baseSize
.
height
for
i
in
1
..<
views
.
count
{
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
base
=
base
,
v
=
views
[
i
]]
in
v
.
alpha
=
0
v
.
y
=
base
.
y
+
h
animations
?(
v
)
})
{
[
weak
self
,
v
=
views
[
i
]]
_
in
guard
let
s
=
self
else
{
return
}
}
v
.
isHidden
=
true
open
var
springDirection
=
SpringDirection
.
up
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
false
}
completion
?(
v
)
}
}
}
/**
Open the Menu component with animation options in the Left direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openLeftAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
for
i
in
1
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
weak
self
,
base
=
base
,
v
=
v
]
in
guard
let
s
=
self
else
{
return
}
v
.
alpha
=
1
v
.
x
=
base
.
x
-
CGFloat
(
i
)
*
s
.
itemSize
.
width
-
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
guard
let
s
=
self
else
{
return
}
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
true
}
completion
?(
v
)
}
}
}
/**
Close the Menu component with animation options in the Left direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeLeftAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
for
i
in
1
..<
views
.
count
{
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
v
=
views
[
i
]]
in
v
.
alpha
=
0
v
.
x
=
base
.
x
animations
?(
v
)
})
{
[
weak
self
,
v
=
views
[
i
]]
_
in
guard
let
s
=
self
else
{
return
}
v
.
isHidden
=
true
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
false
}
completion
?(
v
)
}
}
}
/**
Open the Menu component with animation options in the Right direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openRightAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
let
h
=
baseSize
.
height
for
i
in
1
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
weak
self
,
base
=
base
,
v
=
v
]
in
guard
let
s
=
self
else
{
return
}
v
.
alpha
=
1
v
.
x
=
base
.
x
+
h
+
CGFloat
(
i
-
1
)
*
s
.
itemSize
.
width
+
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
guard
let
s
=
self
else
{
return
}
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
true
}
completion
?(
v
)
}
}
}
/**
Close the Menu component with animation options in the Right direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeRightAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
base
=
views
.
first
else
{
return
}
let
w
=
baseSize
.
width
for
i
in
1
..<
views
.
count
{
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
base
=
base
,
v
=
views
[
i
]]
in
v
.
alpha
=
0
v
.
x
=
base
.
x
+
w
animations
?(
v
)
})
{
[
weak
self
,
v
=
views
[
i
]]
_
in
guard
let
s
=
self
else
{
return
}
v
.
isHidden
=
true
s
.
enable
(
view
:
v
)
if
v
==
s
.
views
.
last
{
s
.
isOpened
=
false
}
completion
?(
v
)
}
}
}
}
}
Sources/iOS/MotionPulse.swift
View file @
542797fb
...
@@ -53,7 +53,7 @@ public protocol Pulseable {
...
@@ -53,7 +53,7 @@ public protocol Pulseable {
var
pulseOpacity
:
CGFloat
{
get
set
}
var
pulseOpacity
:
CGFloat
{
get
set
}
}
}
public
struct
Pulse
{
public
struct
Motion
Pulse
{
/// A UIView that is Pulseable.
/// A UIView that is Pulseable.
fileprivate
weak
var
pulseView
:
UIView
?
fileprivate
weak
var
pulseView
:
UIView
?
...
@@ -64,7 +64,7 @@ public struct Pulse {
...
@@ -64,7 +64,7 @@ public struct Pulse {
fileprivate
var
layers
=
[
CAShapeLayer
]()
fileprivate
var
layers
=
[
CAShapeLayer
]()
/// A reference to the PulseAnimation.
/// A reference to the PulseAnimation.
public
var
animation
=
PulseAnimation
.
pointWithBacking
public
var
animation
=
Motion
PulseAnimation
.
pointWithBacking
/// A UIColor.
/// A UIColor.
public
var
color
=
Color
.
grey
.
base
public
var
color
=
Color
.
grey
.
base
...
@@ -81,7 +81,9 @@ public struct Pulse {
...
@@ -81,7 +81,9 @@ public struct Pulse {
self
.
pulseView
=
pulseView
self
.
pulseView
=
pulseView
self
.
pulseLayer
=
pulseLayer
self
.
pulseLayer
=
pulseLayer
}
}
}
extension
MotionPulse
{
/**
/**
Triggers the expanding animation.
Triggers the expanding animation.
- Parameter point: A point to pulse from.
- Parameter point: A point to pulse from.
...
@@ -157,7 +159,9 @@ public struct Pulse {
...
@@ -157,7 +159,9 @@ public struct Pulse {
bLayer
.
setValue
(
true
,
forKey
:
"animated"
)
bLayer
.
setValue
(
true
,
forKey
:
"animated"
)
}
}
}
}
}
extension
MotionPulse
{
/// Triggers the contracting animation.
/// Triggers the contracting animation.
public
mutating
func
contractAnimation
()
{
public
mutating
func
contractAnimation
()
{
guard
let
bLayer
=
layers
.
popLast
()
else
{
guard
let
bLayer
=
layers
.
popLast
()
else
{
...
...
Sources/iOS/MotionSpring.swift
0 → 100644
View file @
542797fb
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import
UIKit
@objc(SpringDirection)
public
enum
SpringDirection
:
Int
{
case
up
case
down
case
left
case
right
}
public
protocol
Springable
{
/// A SpringDirection value.
var
springDirection
:
SpringDirection
{
get
set
}
}
open
class
MotionSpring
{
/// A SpringDirection value.
open
var
direction
=
SpringDirection
.
up
/// A Boolean that indicates if the menu is open or not.
open
internal(set)
var
isOpened
=
false
/// Enables the animations for the Menu.
open
internal(set)
var
isEnabled
=
true
/// A preset wrapper around interimSpace.
open
var
interimSpacePreset
=
InterimSpacePreset
.
none
{
didSet
{
interimSpace
=
InterimSpacePresetToValue
(
preset
:
interimSpacePreset
)
}
}
/// The space between views.
open
var
interimSpace
:
InterimSpace
=
0
{
didSet
{
reload
()
}
}
/// An Array of UIViews.
open
var
views
=
[
UIView
]()
/// An Optional base view size.
open
var
baseSize
=
CGSize
(
width
:
48
,
height
:
48
)
{
didSet
{
reload
()
}
}
/// Size of views.
open
var
itemSize
=
CGSize
(
width
:
48
,
height
:
48
)
{
didSet
{
reload
()
}
}
/// Reload the view layout.
open
func
reload
()
{
isOpened
=
false
guard
let
first
=
views
.
first
else
{
return
}
first
.
frame
.
size
=
baseSize
first
.
zPosition
=
10000
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
alpha
=
0
v
.
isHidden
=
true
v
.
frame
.
size
=
itemSize
v
.
x
=
first
.
x
+
(
baseSize
.
width
-
itemSize
.
width
)
/
2
v
.
y
=
first
.
y
+
(
baseSize
.
height
-
itemSize
.
height
)
/
2
v
.
zPosition
=
CGFloat
(
10000
-
views
.
count
-
i
)
}
}
}
extension
MotionSpring
{
/// Disable the Menu if views exist.
fileprivate
func
disable
()
{
guard
0
<
views
.
count
else
{
return
}
isEnabled
=
false
}
/**
Enable the Menu if the last view is equal to the passed in view.
- Parameter view: UIView that is passed in to compare.
*/
fileprivate
func
enable
(
view
:
UIView
)
{
guard
view
==
views
.
last
else
{
return
}
isEnabled
=
true
}
}
extension
MotionSpring
{
/**
Open the Menu component with animation options.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
open
func
open
(
duration
:
TimeInterval
=
0.15
,
delay
:
TimeInterval
=
0
,
usingSpringWithDamping
:
CGFloat
=
0.5
,
initialSpringVelocity
:
CGFloat
=
0
,
options
:
UIViewAnimationOptions
=
[],
animations
:
((
UIView
)
->
Void
)?
=
nil
,
completion
:
((
UIView
)
->
Void
)?
=
nil
)
{
guard
isEnabled
else
{
return
}
disable
()
switch
direction
{
case
.
up
:
openUpAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
down
:
openDownAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
left
:
openLeftAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
right
:
openRightAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
}
}
/**
Close the Menu component with animation options.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
open
func
close
(
duration
:
TimeInterval
=
0.15
,
delay
:
TimeInterval
=
0
,
usingSpringWithDamping
:
CGFloat
=
0.5
,
initialSpringVelocity
:
CGFloat
=
0
,
options
:
UIViewAnimationOptions
=
[],
animations
:
((
UIView
)
->
Void
)?
=
nil
,
completion
:
((
UIView
)
->
Void
)?
=
nil
)
{
guard
isEnabled
else
{
return
}
disable
()
switch
direction
{
case
.
up
:
closeUpAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
down
:
closeDownAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
left
:
closeLeftAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
case
.
right
:
closeRightAnimation
(
duration
:
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
animations
,
completion
:
completion
)
}
}
}
extension
MotionSpring
{
/**
Handles the animation open completion.
- Parameter view: A UIView.
- Parameter completion: A completion handler.
*/
fileprivate
func
handleOpenCompletion
(
view
:
UIView
,
completion
:
((
UIView
)
->
Void
)?)
{
enable
(
view
:
view
)
if
view
==
views
.
last
{
isOpened
=
true
}
completion
?(
view
)
}
/**
Handles the animation close completion.
- Parameter view: A UIView.
- Parameter completion: A completion handler.
*/
fileprivate
func
handleCloseCompletion
(
view
:
UIView
,
completion
:
((
UIView
)
->
Void
)?)
{
view
.
isHidden
=
true
enable
(
view
:
view
)
if
view
==
views
.
last
{
isOpened
=
false
}
completion
?(
view
)
}
}
extension
MotionSpring
{
/**
Open the Menu component with animation options in the Up direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openUpAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
s
=
self
,
first
=
first
,
v
=
v
]
in
v
.
alpha
=
1
v
.
y
=
first
.
y
-
CGFloat
(
i
)
*
v
.
height
-
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleOpenCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
/**
Close the Menu component with animation options in the Up direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeUpAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
base
=
first
,
v
=
v
]
in
v
.
alpha
=
0
v
.
y
=
base
.
y
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleCloseCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
/**
Open the Menu component with animation options in the Down direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openDownAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
let
h
=
baseSize
.
height
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
s
=
self
,
first
=
first
,
v
=
v
]
in
v
.
alpha
=
1
v
.
y
=
first
.
y
+
h
+
CGFloat
(
i
-
1
)
*
s
.
itemSize
.
height
+
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleOpenCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
/**
Close the Menu component with animation options in the Down direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeDownAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
let
h
=
baseSize
.
height
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
first
=
first
,
v
=
v
]
in
v
.
alpha
=
0
v
.
y
=
first
.
y
+
h
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleCloseCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
/**
Open the Menu component with animation options in the Left direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openLeftAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
s
=
self
,
first
=
first
,
v
=
v
]
in
v
.
alpha
=
1
v
.
x
=
first
.
x
-
CGFloat
(
i
)
*
s
.
itemSize
.
width
-
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleOpenCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
/**
Close the Menu component with animation options in the Left direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeLeftAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
first
=
first
,
v
=
v
]
in
v
.
alpha
=
0
v
.
x
=
first
.
x
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleCloseCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
/**
Open the Menu component with animation options in the Right direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
openRightAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
let
h
=
baseSize
.
height
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
v
.
isHidden
=
false
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
s
=
self
,
first
=
first
,
v
=
v
]
in
v
.
alpha
=
1
v
.
x
=
first
.
x
+
h
+
CGFloat
(
i
-
1
)
*
s
.
itemSize
.
width
+
CGFloat
(
i
)
*
s
.
interimSpace
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleOpenCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
/**
Close the Menu component with animation options in the Right direction.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
- Parameter usingSpringWithDamping: A damping ratio for the animation.
- Parameter initialSpringVelocity: The initial velocity for the animation.
- Parameter options: Options to pass to the animation.
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
fileprivate
func
closeRightAnimation
(
duration
:
TimeInterval
,
delay
:
TimeInterval
,
usingSpringWithDamping
:
CGFloat
,
initialSpringVelocity
:
CGFloat
,
options
:
UIViewAnimationOptions
,
animations
:
((
UIView
)
->
Void
)?,
completion
:
((
UIView
)
->
Void
)?)
{
guard
let
first
=
views
.
first
else
{
return
}
let
w
=
baseSize
.
width
for
i
in
0
..<
views
.
count
{
let
v
=
views
[
i
]
UIView
.
animate
(
withDuration
:
Double
(
i
)
*
duration
,
delay
:
delay
,
usingSpringWithDamping
:
usingSpringWithDamping
,
initialSpringVelocity
:
initialSpringVelocity
,
options
:
options
,
animations
:
{
[
first
=
first
,
v
=
v
]
in
v
.
alpha
=
0
v
.
x
=
first
.
x
+
w
animations
?(
v
)
})
{
[
weak
self
,
v
=
v
]
_
in
self
?
.
handleCloseCompletion
(
view
:
v
,
completion
:
completion
)
}
}
}
}
Sources/iOS/PulseView.swift
View file @
542797fb
...
@@ -32,7 +32,7 @@ import UIKit
...
@@ -32,7 +32,7 @@ import UIKit
open
class
PulseView
:
View
,
Pulseable
{
open
class
PulseView
:
View
,
Pulseable
{
/// A Pulse reference.
/// A Pulse reference.
fileprivate
var
pulse
:
Pulse
!
fileprivate
var
pulse
:
Motion
Pulse
!
/// PulseAnimation value.
/// PulseAnimation value.
open
var
pulseAnimation
:
PulseAnimation
{
open
var
pulseAnimation
:
PulseAnimation
{
...
@@ -129,6 +129,6 @@ open class PulseView: View, Pulseable {
...
@@ -129,6 +129,6 @@ open class PulseView: View, Pulseable {
extension
PulseView
{
extension
PulseView
{
/// Prepares the pulse motion.
/// Prepares the pulse motion.
fileprivate
func
preparePulse
()
{
fileprivate
func
preparePulse
()
{
pulse
=
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
pulse
=
Motion
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
}
}
}
}
Sources/iOS/TableViewCell.swift
View file @
542797fb
...
@@ -40,7 +40,7 @@ open class TableViewCell: UITableViewCell, Pulseable {
...
@@ -40,7 +40,7 @@ open class TableViewCell: UITableViewCell, Pulseable {
open
let
visualLayer
=
CAShapeLayer
()
open
let
visualLayer
=
CAShapeLayer
()
/// A Pulse reference.
/// A Pulse reference.
fileprivate
var
pulse
:
Pulse
!
fileprivate
var
pulse
:
Motion
Pulse
!
/// PulseAnimation value.
/// PulseAnimation value.
open
var
pulseAnimation
:
PulseAnimation
{
open
var
pulseAnimation
:
PulseAnimation
{
...
@@ -177,7 +177,7 @@ open class TableViewCell: UITableViewCell, Pulseable {
...
@@ -177,7 +177,7 @@ open class TableViewCell: UITableViewCell, Pulseable {
extension
TableViewCell
{
extension
TableViewCell
{
/// Prepares the pulse motion.
/// Prepares the pulse motion.
fileprivate
func
preparePulse
()
{
fileprivate
func
preparePulse
()
{
pulse
=
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
pulse
=
Motion
Pulse
(
pulseView
:
self
,
pulseLayer
:
visualLayer
)
}
}
/// Prepares the visualLayer property.
/// Prepares the visualLayer property.
...
...
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