Commit 63d8d3af by Daniel Dahan

development: working FABMenu with MotionSpring

parent abd72e41
...@@ -190,9 +190,9 @@ open class Button: UIButton, MotionPulseable { ...@@ -190,9 +190,9 @@ open class Button: UIButton, MotionPulseable {
open func pulse(point: CGPoint? = nil) { open func pulse(point: CGPoint? = nil) {
let p = point ?? center let p = point ?? center
pulse.expandAnimation(point: p) pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in Motion.delay(time: 0.35) { [weak self] in
self?.pulse.contractAnimation() self?.pulse.contract()
} }
} }
...@@ -204,7 +204,7 @@ open class Button: UIButton, MotionPulseable { ...@@ -204,7 +204,7 @@ open class Button: UIButton, MotionPulseable {
*/ */
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) super.touchesBegan(touches, with: event)
pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer))
} }
/** /**
...@@ -215,7 +215,7 @@ open class Button: UIButton, MotionPulseable { ...@@ -215,7 +215,7 @@ open class Button: UIButton, MotionPulseable {
*/ */
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event) super.touchesEnded(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
...@@ -226,7 +226,7 @@ open class Button: UIButton, MotionPulseable { ...@@ -226,7 +226,7 @@ open class Button: UIButton, MotionPulseable {
*/ */
open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event) super.touchesCancelled(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
open func bringImageViewToFront() { open func bringImageViewToFront() {
......
...@@ -239,9 +239,9 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable { ...@@ -239,9 +239,9 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable {
open func pulse(point: CGPoint? = nil) { open func pulse(point: CGPoint? = nil) {
let p = point ?? center let p = point ?? center
pulse.expandAnimation(point: p) pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in Motion.delay(time: 0.35) { [weak self] in
self?.pulse.contractAnimation() self?.pulse.contract()
} }
} }
...@@ -253,7 +253,7 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable { ...@@ -253,7 +253,7 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable {
*/ */
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) super.touchesBegan(touches, with: event)
pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer))
} }
/** /**
...@@ -264,7 +264,7 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable { ...@@ -264,7 +264,7 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable {
*/ */
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event) super.touchesEnded(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
...@@ -275,7 +275,7 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable { ...@@ -275,7 +275,7 @@ open class CollectionReusableView: UICollectionReusableView, MotionPulseable {
*/ */
open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event) super.touchesCancelled(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
......
...@@ -200,9 +200,9 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable { ...@@ -200,9 +200,9 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable {
open func pulse(point: CGPoint? = nil) { open func pulse(point: CGPoint? = nil) {
let p = point ?? center let p = point ?? center
pulse.expandAnimation(point: p) pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in Motion.delay(time: 0.35) { [weak self] in
self?.pulse.contractAnimation() self?.pulse.contract()
} }
} }
...@@ -214,7 +214,7 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable { ...@@ -214,7 +214,7 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable {
*/ */
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) super.touchesBegan(touches, with: event)
pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer))
} }
/** /**
...@@ -225,7 +225,7 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable { ...@@ -225,7 +225,7 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable {
*/ */
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event) super.touchesEnded(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
...@@ -236,7 +236,7 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable { ...@@ -236,7 +236,7 @@ open class CollectionViewCell: UICollectionViewCell, MotionPulseable {
*/ */
open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event) super.touchesCancelled(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
......
...@@ -53,25 +53,98 @@ public protocol FABMenuDelegate { ...@@ -53,25 +53,98 @@ public protocol FABMenuDelegate {
@objc(FABMenu) @objc(FABMenu)
open class FABMenu: Menu { open class FABMenu: View, MotionSpringable {
/// An optional delegation handler. /// A reference to the MotionSpring object.
open weak var delegate: FABMenuDelegate? internal let spring = MotionSpring()
/// The direction in which the animation opens the menu. /// The direction in which the animation opens the menu.
open var direction = SpringDirection.up { open var springDirection = MotionSpringDirection.up {
didSet { didSet {
layoutSubviews() layoutSubviews()
} }
} }
/// A reference to the MenuItems open var baseSize: CGSize {
open var buttons: [MenuItem] { get {
return spring.baseSize
}
set(value) {
spring.baseSize = value
}
}
open var itemSize: CGSize {
get { get {
return views as! [MenuItem] return spring.itemSize
} }
set(value) { set(value) {
views = value spring.itemSize = value
}
}
open var isOpened: Bool {
get {
return spring.isOpened
}
set(value) {
spring.isOpened = value
}
} }
open var isEnable: Bool {
get {
return spring.isEnabled
}
set(value) {
spring.isEnabled = value
}
}
/// A preset wrapper around interimSpace.
open var interimSpacePreset: InterimSpacePreset {
get {
return spring.interimSpacePreset
}
set(value) {
spring.interimSpacePreset = value
}
}
/// The space between views.
open var interimSpace: InterimSpace {
get {
return spring.interimSpace
}
set(value) {
spring.interimSpace = value
}
}
/// An optional delegation handler.
open weak var delegate: FABMenuDelegate?
/// A reference to the FABMenuItems
open var items: [FABMenuItem] {
get {
return spring.views as! [FABMenuItem]
}
set(value) {
for v in spring.views {
v.removeFromSuperview()
}
for v in value {
addSubview(v)
}
spring.views = value
}
}
open override func prepare() {
super.prepare()
backgroundColor = nil
interimSpacePreset = .interimSpace6
} }
} }
...@@ -83,7 +156,7 @@ extension FABMenu { ...@@ -83,7 +156,7 @@ extension FABMenu {
- Returns: An optional UIView. - Returns: An optional UIView.
*/ */
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard isOpened, isEnabled else { guard spring.isOpened, spring.isEnabled else {
return super.hitTest(point, with: event) return super.hitTest(point, with: event)
} }
...@@ -100,3 +173,33 @@ extension FABMenu { ...@@ -100,3 +173,33 @@ extension FABMenu {
return self.hitTest(point, with: event) return self.hitTest(point, with: event)
} }
} }
extension FABMenu {
/**
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) {
spring.expand(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) {
spring.contract(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
}
}
...@@ -89,12 +89,14 @@ extension FABMenuController { ...@@ -89,12 +89,14 @@ extension FABMenuController {
open func openMenu(completion: ((UIView) -> Void)? = nil) { open func openMenu(completion: ((UIView) -> Void)? = nil) {
if true == isUserInteractionEnabled { if true == isUserInteractionEnabled {
isUserInteractionEnabled = false isUserInteractionEnabled = false
UIView.animate(withDuration: 0.15, animations: { [weak self] in UIView.animate(withDuration: 0.15, animations: { [weak self] in
guard let s = self else { guard let s = self else {
return return
} }
s.rootViewController.view.alpha = 0.15 s.rootViewController.view.alpha = 0.15
}) })
menu.open { [completion = completion] (view) in menu.open { [completion = completion] (view) in
completion?(view) completion?(view)
} }
...@@ -114,6 +116,7 @@ extension FABMenuController { ...@@ -114,6 +116,7 @@ extension FABMenuController {
} }
s.rootViewController.view.alpha = 1 s.rootViewController.view.alpha = 1
}) })
menu.close { [weak self] (view) in menu.close { [weak self] (view) in
guard let s = self else { guard let s = self else {
return return
...@@ -121,7 +124,7 @@ extension FABMenuController { ...@@ -121,7 +124,7 @@ extension FABMenuController {
completion?(view) completion?(view)
if view == s.menu.views.last { if view == s.menu.items.last {
s.isUserInteractionEnabled = true s.isUserInteractionEnabled = true
} }
} }
......
...@@ -30,10 +30,44 @@ ...@@ -30,10 +30,44 @@
import UIKit import UIKit
@objc(menu) @objc(MenuDirection)
public enum MenuDirection: Int {
case up
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)
}
@objc(Menu)
open class Menu: View, MotionSpringable { open class Menu: View, MotionSpringable {
internal let spring = Spring() /// A reference to the MotionSpring object.
internal let spring = MotionSpring()
/// An optional delegation handler.
open weak var delegate: MenuDelegate?
/// The direction in which the animation opens the menu.
open var springDirection = MotionSpringDirection.up {
didSet {
layoutSubviews()
}
}
/// A reference to the MenuItems
open var views: [UIView] { open var views: [UIView] {
get { get {
return spring.views return spring.views
...@@ -42,6 +76,60 @@ open class Menu: View, MotionSpringable { ...@@ -42,6 +76,60 @@ open class Menu: View, MotionSpringable {
spring.views = value spring.views = value
} }
} }
}
extension Menu {
/**
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 spring.isOpened, spring.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)
}
}
open var springDirection = SpringDirection.up delegate?.menu?(menu: self, tappedAt: point, isOutside: true)
return self.hitTest(point, with: event)
}
}
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) {
spring.expand(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) {
spring.contract(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
}
} }
...@@ -51,7 +51,7 @@ extension UIViewController { ...@@ -51,7 +51,7 @@ extension UIViewController {
open class MenuController: RootController { open class MenuController: RootController {
/// Reference to the MenuView. /// Reference to the MenuView.
@IBInspectable @IBInspectable
open let menu = FABMenu() open let menu = Menu()
open override func layoutSubviews() { open override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
...@@ -88,12 +88,14 @@ extension MenuController { ...@@ -88,12 +88,14 @@ extension MenuController {
open func openMenu(completion: ((UIView) -> Void)? = nil) { open func openMenu(completion: ((UIView) -> Void)? = nil) {
if true == isUserInteractionEnabled { if true == isUserInteractionEnabled {
isUserInteractionEnabled = false isUserInteractionEnabled = false
UIView.animate(withDuration: 0.15, animations: { [weak self] in UIView.animate(withDuration: 0.15, animations: { [weak self] in
guard let s = self else { guard let s = self else {
return return
} }
s.rootViewController.view.alpha = 0.15 s.rootViewController.view.alpha = 0.15
}) })
menu.open(usingSpringWithDamping: 0) { [completion = completion] (view) in menu.open(usingSpringWithDamping: 0) { [completion = completion] (view) in
completion?(view) completion?(view)
} }
...@@ -113,6 +115,7 @@ extension MenuController { ...@@ -113,6 +115,7 @@ extension MenuController {
} }
s.rootViewController.view.alpha = 1 s.rootViewController.view.alpha = 1
}) })
menu.close(usingSpringWithDamping: 0) { [weak self] (view) in menu.close(usingSpringWithDamping: 0) { [weak self] (view) in
guard let s = self else { guard let s = self else {
return return
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
import UIKit import UIKit
open class MenuItem: View { open class FABMenuItem: View {
/// A reference to the titleLabel. /// A reference to the titleLabel.
open let titleLabel = UILabel() open let titleLabel = UILabel()
......
...@@ -64,7 +64,7 @@ public struct MotionPulse { ...@@ -64,7 +64,7 @@ public struct MotionPulse {
fileprivate var layers = [CAShapeLayer]() fileprivate var layers = [CAShapeLayer]()
/// A reference to the MotionPulseAnimation. /// A reference to the MotionPulseAnimation.
public var animation = MotionMotionPulseAnimation.pointWithBacking public var animation = MotionPulseAnimation.pointWithBacking
/// A UIColor. /// A UIColor.
public var color = Color.grey.base public var color = Color.grey.base
...@@ -88,7 +88,7 @@ extension MotionPulse { ...@@ -88,7 +88,7 @@ extension MotionPulse {
Triggers the expanding animation. Triggers the expanding animation.
- Parameter point: A point to pulse from. - Parameter point: A point to pulse from.
*/ */
public mutating func expandAnimation(point: CGPoint) { public mutating func expand(point: CGPoint) {
guard let view = pulseView else { guard let view = pulseView else {
return return
} }
...@@ -163,7 +163,7 @@ extension MotionPulse { ...@@ -163,7 +163,7 @@ extension MotionPulse {
extension MotionPulse { extension MotionPulse {
/// Triggers the contracting animation. /// Triggers the contracting animation.
public mutating func contractAnimation() { public mutating func contract() {
guard let bLayer = layers.popLast() else { guard let bLayer = layers.popLast() else {
return return
} }
......
...@@ -48,10 +48,10 @@ open class MotionSpring { ...@@ -48,10 +48,10 @@ open class MotionSpring {
open var direction = MotionSpringDirection.up open var direction = MotionSpringDirection.up
/// A Boolean that indicates if the menu is open or not. /// A Boolean that indicates if the menu is open or not.
open internal(set) var isOpened = false open var isOpened = false
/// Enables the animations for the Menu. /// Enables the animations for the Menu.
open internal(set) var isEnabled = true open var isEnabled = true
/// A preset wrapper around interimSpace. /// A preset wrapper around interimSpace.
open var interimSpacePreset = InterimSpacePreset.none { open var interimSpacePreset = InterimSpacePreset.none {
...@@ -68,7 +68,11 @@ open class MotionSpring { ...@@ -68,7 +68,11 @@ open class MotionSpring {
} }
/// An Array of UIViews. /// An Array of UIViews.
open var views = [UIView]() open var views = [UIView]() {
didSet {
reload()
}
}
/// An Optional base view size. /// An Optional base view size.
open var baseSize = CGSize(width: 48, height: 48) { open var baseSize = CGSize(width: 48, height: 48) {
...@@ -95,7 +99,7 @@ open class MotionSpring { ...@@ -95,7 +99,7 @@ open class MotionSpring {
first.frame.size = baseSize first.frame.size = baseSize
first.zPosition = 10000 first.zPosition = 10000
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
v.alpha = 0 v.alpha = 0
v.isHidden = true v.isHidden = true
...@@ -132,7 +136,7 @@ extension MotionSpring { ...@@ -132,7 +136,7 @@ extension MotionSpring {
extension MotionSpring { extension MotionSpring {
/** /**
Open the Menu component with animation options. Expands the Spring component with animation options.
- Parameter duration: The time for each view's animation. - Parameter duration: The time for each view's animation.
- Parameter delay: A delay 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 usingSpringWithDamping: A damping ratio for the animation.
...@@ -141,7 +145,7 @@ extension MotionSpring { ...@@ -141,7 +145,7 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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) { open func expand(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 { guard isEnabled else {
return return
} }
...@@ -150,18 +154,18 @@ extension MotionSpring { ...@@ -150,18 +154,18 @@ extension MotionSpring {
switch direction { switch direction {
case .up: case .up:
openUpAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) expandUp(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
case .down: case .down:
openDownAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) expandDown(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
case .left: case .left:
openLeftAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) expandLeft(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
case .right: case .right:
openRightAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) expandRight(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
} }
} }
/** /**
Close the Menu component with animation options. Contracts the Spring component with animation options.
- Parameter duration: The time for each view's animation. - Parameter duration: The time for each view's animation.
- Parameter delay: A delay 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 usingSpringWithDamping: A damping ratio for the animation.
...@@ -170,7 +174,7 @@ extension MotionSpring { ...@@ -170,7 +174,7 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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) { open func contract(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 { guard isEnabled else {
return return
} }
...@@ -179,13 +183,13 @@ extension MotionSpring { ...@@ -179,13 +183,13 @@ extension MotionSpring {
switch direction { switch direction {
case .up: case .up:
closeUpAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) contractUp(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
case .down: case .down:
closeDownAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) contractDown(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
case .left: case .left:
closeLeftAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) contractLeft(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
case .right: case .right:
closeRightAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) contractRight(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion)
} }
} }
} }
...@@ -207,7 +211,7 @@ extension MotionSpring { ...@@ -207,7 +211,7 @@ extension MotionSpring {
} }
/** /**
Handles the animation close completion. Handles the animation contract completion.
- Parameter view: A UIView. - Parameter view: A UIView.
- Parameter completion: A completion handler. - Parameter completion: A completion handler.
*/ */
...@@ -234,12 +238,12 @@ extension MotionSpring { ...@@ -234,12 +238,12 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func expandUp(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
v.isHidden = false v.isHidden = false
...@@ -269,12 +273,12 @@ extension MotionSpring { ...@@ -269,12 +273,12 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func contractUp(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
UIView.animate(withDuration: Double(i) * duration, UIView.animate(withDuration: Double(i) * duration,
...@@ -303,14 +307,14 @@ extension MotionSpring { ...@@ -303,14 +307,14 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func expandDown(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
let h = baseSize.height let h = baseSize.height
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
v.isHidden = false v.isHidden = false
...@@ -340,14 +344,14 @@ extension MotionSpring { ...@@ -340,14 +344,14 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func contractDown(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
let h = baseSize.height let h = baseSize.height
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
UIView.animate(withDuration: Double(i) * duration, UIView.animate(withDuration: Double(i) * duration,
...@@ -376,12 +380,12 @@ extension MotionSpring { ...@@ -376,12 +380,12 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func expandLeft(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
v.isHidden = false v.isHidden = false
...@@ -411,12 +415,12 @@ extension MotionSpring { ...@@ -411,12 +415,12 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func contractLeft(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
UIView.animate(withDuration: Double(i) * duration, UIView.animate(withDuration: Double(i) * duration,
...@@ -445,14 +449,14 @@ extension MotionSpring { ...@@ -445,14 +449,14 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func expandRight(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
let h = baseSize.height let h = baseSize.height
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
v.isHidden = false v.isHidden = false
...@@ -482,14 +486,14 @@ extension MotionSpring { ...@@ -482,14 +486,14 @@ extension MotionSpring {
- Parameter animations: An animation block to execute on each view's 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. - 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)?) { fileprivate func contractRight(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let first = views.first else { guard let first = views.first else {
return return
} }
let w = baseSize.width let w = baseSize.width
for i in 0..<views.count { for i in 1..<views.count {
let v = views[i] let v = views[i]
UIView.animate(withDuration: Double(i) * duration, UIView.animate(withDuration: Double(i) * duration,
......
...@@ -74,9 +74,9 @@ open class PulseView: View, MotionPulseable { ...@@ -74,9 +74,9 @@ open class PulseView: View, MotionPulseable {
open func pulse(point: CGPoint? = nil) { open func pulse(point: CGPoint? = nil) {
let p = point ?? center let p = point ?? center
pulse.expandAnimation(point: p) pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in Motion.delay(time: 0.35) { [weak self] in
self?.pulse.contractAnimation() self?.pulse.contract()
} }
} }
...@@ -88,7 +88,7 @@ open class PulseView: View, MotionPulseable { ...@@ -88,7 +88,7 @@ open class PulseView: View, MotionPulseable {
*/ */
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) super.touchesBegan(touches, with: event)
pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer))
} }
/** /**
...@@ -99,7 +99,7 @@ open class PulseView: View, MotionPulseable { ...@@ -99,7 +99,7 @@ open class PulseView: View, MotionPulseable {
*/ */
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event) super.touchesEnded(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
...@@ -110,7 +110,7 @@ open class PulseView: View, MotionPulseable { ...@@ -110,7 +110,7 @@ open class PulseView: View, MotionPulseable {
*/ */
open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event) super.touchesCancelled(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
......
...@@ -116,9 +116,9 @@ open class TableViewCell: UITableViewCell, MotionPulseable { ...@@ -116,9 +116,9 @@ open class TableViewCell: UITableViewCell, MotionPulseable {
open func pulse(point: CGPoint? = nil) { open func pulse(point: CGPoint? = nil) {
let p = point ?? center let p = point ?? center
pulse.expandAnimation(point: p) pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in Motion.delay(time: 0.35) { [weak self] in
self?.pulse.contractAnimation() self?.pulse.contract()
} }
} }
...@@ -130,7 +130,7 @@ open class TableViewCell: UITableViewCell, MotionPulseable { ...@@ -130,7 +130,7 @@ open class TableViewCell: UITableViewCell, MotionPulseable {
*/ */
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) super.touchesBegan(touches, with: event)
pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer))
} }
/** /**
...@@ -141,7 +141,7 @@ open class TableViewCell: UITableViewCell, MotionPulseable { ...@@ -141,7 +141,7 @@ open class TableViewCell: UITableViewCell, MotionPulseable {
*/ */
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event) super.touchesEnded(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
...@@ -152,7 +152,7 @@ open class TableViewCell: UITableViewCell, MotionPulseable { ...@@ -152,7 +152,7 @@ open class TableViewCell: UITableViewCell, MotionPulseable {
*/ */
open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event) super.touchesCancelled(touches, with: event)
pulse.contractAnimation() pulse.contract()
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment