Commit 95bee682 by Daniel Dahan

initial SideNavigationViewController prototype

parent 6224b1aa
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'MK' s.name = 'MK'
s.version = '1.23.0' s.version = '1.22.0'
s.license = { :type => "AGPLv3+", :file => "LICENSE" } s.license = { :type => "AGPLv3+", :file => "LICENSE" }
s.summary = 'A Material Design Framework In Swift' s.summary = 'A Material Design Framework In Swift'
s.homepage = 'http://materialkit.io' s.homepage = 'http://materialkit.io'
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.23.0</string> <string>1.22.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
......
...@@ -67,10 +67,11 @@ public struct MaterialAnimation { ...@@ -67,10 +67,11 @@ public struct MaterialAnimation {
/** /**
:name: animationWithDuration :name: animationWithDuration
*/ */
public static func animationWithDuration(duration: CFTimeInterval, animations: (() -> Void), completion: (() -> Void)? = nil) { public static func animationWithDuration(duration: CFTimeInterval, animations: (() -> Void), options: UIViewAnimationOptions? = nil, completion: (() -> Void)? = nil) {
CATransaction.begin() CATransaction.begin()
CATransaction.setAnimationDuration(duration) CATransaction.setAnimationDuration(duration)
CATransaction.setCompletionBlock(completion) CATransaction.setCompletionBlock(completion)
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut))
animations() animations()
CATransaction.commit() CATransaction.commit()
} }
......
...@@ -522,8 +522,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell, UIGestureRecogni ...@@ -522,8 +522,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell, UIGestureRecogni
delegate?.materialCollectionViewCellDidCloseRightLayer?(self) delegate?.materialCollectionViewCellDidCloseRightLayer?(self)
} }
default: default:break
break
} }
} }
......
...@@ -34,57 +34,6 @@ public extension UIViewController { ...@@ -34,57 +34,6 @@ public extension UIViewController {
} }
} }
public enum SideNavigationViewState {
case Opened
case Closed
}
@objc(SideNavigationViewContainer)
public class SideNavigationViewContainer : NSObject {
/**
:name: state
*/
public private(set) var state: SideNavigationViewState
/**
:name: point
*/
public private(set) var point: CGPoint
/**
:name: frame
*/
public private(set) var frame: CGRect
/**
:name: description
*/
public override var description: String {
let s: String = .Opened == state ? "Opened" : "Closed"
return "(state: \(s), point: \(point), frame: \(frame))"
}
/**
:name: init
*/
public init(state: SideNavigationViewState, point: CGPoint, frame: CGRect) {
self.state = state
self.point = point
self.frame = frame
}
}
@objc(SideNavigationViewDelegate)
public protocol SideNavigationViewDelegate {
// left
optional func sideNavDidBeginLeftPan(nav: SideNavigationViewController, container: SideNavigationViewContainer)
optional func sideNavDidChangeLeftPan(nav: SideNavigationViewController, container: SideNavigationViewContainer)
optional func sideNavDidEndLeftPan(nav: SideNavigationViewController, container: SideNavigationViewContainer)
optional func sideNavDidOpenLeftViewContainer(nav: SideNavigationViewController, container: SideNavigationViewContainer)
optional func sideNavDidCloseLeftViewContainer(nav: SideNavigationViewController, container: SideNavigationViewContainer)
optional func sideNavDidTapLeft(nav: SideNavigationViewController, container: SideNavigationViewContainer)
}
@objc(SideNavigationViewController) @objc(SideNavigationViewController)
public class SideNavigationViewController: UIViewController, UIGestureRecognizerDelegate { public class SideNavigationViewController: UIViewController, UIGestureRecognizerDelegate {
/** /**
...@@ -95,7 +44,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -95,7 +44,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
public static var bezelHeight: CGFloat = 48 public static var bezelHeight: CGFloat = 48
public static var containerWidth: CGFloat = 240 public static var containerWidth: CGFloat = 240
public static var containerHeight: CGFloat = 240 public static var containerHeight: CGFloat = 240
public static var defaultAnimationDuration: CGFloat = 0.3 public static var defaultAnimationDuration: CGFloat = 0.25
public static var threshold: CGFloat = 48 public static var threshold: CGFloat = 48
public static var panningEnabled: Bool = true public static var panningEnabled: Bool = true
} }
...@@ -120,11 +69,6 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -120,11 +69,6 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
} }
/** /**
:name: delegate
*/
public weak var delegate: SideNavigationViewDelegate?
/**
:name: isViewBasedAppearance :name: isViewBasedAppearance
*/ */
public var isViewBasedAppearance: Bool { public var isViewBasedAppearance: Bool {
...@@ -153,25 +97,25 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -153,25 +97,25 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
} }
} }
//
// :name: originalPosition
//
private var originalPosition: CGPoint!
/** /**
:name: backdropViewContainer :name: backdropLayer
*/ */
public private(set) var backdropViewContainer: UIView? public private(set) lazy var backdropLayer: MaterialLayer = MaterialLayer()
/** /**
:name: mainViewContainer :name: mainViewContainer
*/ */
public private(set) var mainViewContainer: UIView? public private(set) var mainViewContainer: MaterialView?
/** /**
:name: leftViewContainer :name: leftViewContainer
*/ */
public private(set) var leftViewContainer: UIView? public private(set) var leftViewContainer: MaterialView?
/**
:name: leftContainer
*/
public private(set) var leftContainer: SideNavigationViewContainer?
/** /**
:name: mainViewController :name: mainViewController
...@@ -184,6 +128,11 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -184,6 +128,11 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
public var leftViewController: UIViewController? public var leftViewController: UIViewController?
/** /**
:name: leftAnimation
*/
private var leftAnimation: CAAnimation?
/**
:name: leftPanGesture :name: leftPanGesture
*/ */
public var leftPanGesture: UIPanGestureRecognizer? public var leftPanGesture: UIPanGestureRecognizer?
...@@ -252,7 +201,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -252,7 +201,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
} }
if nil != leftViewController { if nil != leftViewController {
prepareContainedViewController(&leftViewContainer, viewController: &leftViewController) // prepareContainedViewController(&leftViewContainer, viewController: &leftViewController)
} }
} }
...@@ -260,7 +209,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -260,7 +209,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
:name: toggleLeftViewContainer :name: toggleLeftViewContainer
*/ */
public func toggleLeftViewContainer(velocity: CGFloat = 0) { public func toggleLeftViewContainer(velocity: CGFloat = 0) {
isLeftContainerOpened ? closeLeftViewContainer(velocity) : openLeftViewContainer(velocity) openLeftViewContainer(velocity)
} }
/** /**
...@@ -268,71 +217,41 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -268,71 +217,41 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
*/ */
public func openLeftViewContainer(velocity: CGFloat = 0) { public func openLeftViewContainer(velocity: CGFloat = 0) {
if let vc = leftViewContainer { if let vc = leftViewContainer {
if let c = leftContainer {
prepareContainerToOpen(&leftViewController, viewContainer: &leftViewContainer, state: c.state)
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(vc.frame.origin.x / velocity)))),
delay: 0,
options: .CurveEaseInOut,
animations: { _ in
vc.frame.origin.x = 0
self.backdropViewContainer?.layer.opacity = Float(options.backdropOpacity)
self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.backdropScale, options.backdropScale)
}
) { _ in
self.isUserInteractionEnabled = false
}
c.state = .Opened
delegate?.sideNavDidOpenLeftViewContainer?(self, container: c)
}
}
}
/** let w: CGFloat = vc.width
:name: closeLeftViewContainer let h: CGFloat = vc.height
*/ let d: Double = Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(vc.frame.origin.x / velocity))))
public func closeLeftViewContainer(velocity: CGFloat = 0) {
if let vc = leftViewContainer {
if let c = leftContainer {
prepareContainerToClose(&leftViewController, state: c.state)
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, fabs(vc.frame.origin.x - leftOriginX) / velocity))),
delay: 0,
options: .CurveEaseInOut,
animations: { _ in
vc.frame.origin.x = self.leftOriginX
self.backdropViewContainer?.layer.opacity = 0
self.mainViewContainer?.transform = CGAffineTransformMakeScale(1, 1)
}
) { _ in
self.removeShadow(&self.leftViewContainer)
self.isUserInteractionEnabled = true
}
c.state = .Closed
delegate?.sideNavDidCloseLeftViewContainer?(self, container: c)
}
}
}
/** vc.shadowDepth = .None
:name: switchMainViewController
*/ MaterialAnimation.animationWithDuration(d, animations: {
public func switchMainViewController(viewController: UIViewController, closeViewContainers: Bool) { vc.position = CGPointMake(w / 2, h / 2)
removeViewController(&mainViewController) self.backdropLayer.opacity = Float(options.backdropOpacity)
mainViewController = viewController }) {
prepareContainedViewController(&mainViewContainer, viewController: &mainViewController) self.isUserInteractionEnabled = false
if closeViewContainers { // vc.shadowDepth = .Depth2
closeLeftViewContainer()
}
} }
/** // print(vc.frame)
:name: switchLeftViewController // let a: CABasicAnimation = MaterialAnimation.position(CGPointMake(w / 2, h / 2), duration: d)
*/ // a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
public func switchLeftViewController(viewController: UIViewController, closeLeftViewContainerViewContainer: Bool) { // vc.animation(a)
removeViewController(&leftViewController) //
leftViewController = viewController ////
prepareContainedViewController(&leftViewContainer, viewController: &leftViewController) // UIView.animateWithDuration(d,
if closeLeftViewContainerViewContainer { // delay: 0,
closeLeftViewContainer() // options: .CurveEaseInOut,
// animations: { _ in
// vc.frame.origin.x = 0
// self.backdropViewContainer?.layer.opacity = Float(options.backdropOpacity)
// self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.backdropScale, options.backdropScale)
// }
// ) { _ in
// self.isUserInteractionEnabled = false
// }
// c.state = .Opened
// delegate?.sideNavDidOpenLeftViewContainer?(self, container: c)
} }
} }
...@@ -361,8 +280,15 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -361,8 +280,15 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
// :name: prepareLeftView // :name: prepareLeftView
// //
internal func prepareLeftView() { internal func prepareLeftView() {
prepareContainer(&leftContainer, viewContainer: &leftViewContainer, originX: leftOriginX, originY: 0, width: options.leftViewContainerWidth, height: view.bounds.size.height) prepareContainer(&leftViewContainer, originX: leftOriginX, originY: 0, width: options.leftViewContainerWidth, height: view.bounds.size.height)
prepareLeftGestures() prepareLeftGestures()
// leftViewContainer!.layer.speed = 0
let w: CGFloat = leftViewContainer!.width
let h: CGFloat = leftViewContainer!.height
// leftAnimation = MaterialAnimation.position(CGPointMake(w / 2, h / 2), duration: 1)
// leftViewContainer!.position = CGPointMake(-(w / 2), h / 2)
// leftViewContainer!.animation(leftAnimation!)
} }
// //
...@@ -398,36 +324,30 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -398,36 +324,30 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
// //
// :name: handleLeftPanGesture // :name: handleLeftPanGesture
// //
internal func handleLeftPanGesture(gesture: UIPanGestureRecognizer) { internal func handleLeftPanGesture(recognizer: UIPanGestureRecognizer) {
if let vc = leftViewContainer { if let vc = leftViewContainer {
if let c = leftContainer { switch recognizer.state {
if .Began == gesture.state { case .Began:
addShadow(&leftViewContainer) originalPosition = vc.position
toggleStatusBar(true) toggleStatusBar(true)
c.state = isLeftContainerOpened ? .Opened : .Closed case .Changed:
c.point = gesture.locationInView(view) let translation: CGPoint = recognizer.translationInView(vc)
c.frame = vc.frame let w: CGFloat = leftViewContainer!.width
delegate?.sideNavDidBeginLeftPan?(self, container: c)
} else if .Changed == gesture.state { MaterialAnimation.animationDisabled({
c.point = gesture.translationInView(gesture.view!) vc.position.x = self.originalPosition.x + translation.x > (w / 2) ? (w / 2) : self.originalPosition.x + translation.x
let r = (vc.frame.origin.x - leftOriginX) / vc.frame.size.width self.backdropLayer.opacity = Float(vc.position.x / (w / 2)) / 2
let s: CGFloat = 1 - (1 - options.backdropScale) * r })
let x: CGFloat = c.frame.origin.x + c.point.x case .Ended:
vc.frame.origin.x = x < leftOriginX ? leftOriginX : x > 0 ? 0 : x self.isUserInteractionEnabled = false
backdropViewContainer?.layer.opacity = Float(r * options.backdropOpacity) // snap back
mainViewContainer?.transform = CGAffineTransformMakeScale(s, s) let a: CABasicAnimation = MaterialAnimation.position(CGPointMake(vc.width / 2, vc.height / 2), duration: 0.25)
delegate?.sideNavDidChangeLeftPan?(self, container: c) a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
} else { vc.animation(a)
c.point = gesture.velocityInView(gesture.view)
let x: CGFloat = c.point.x >= 1000 || c.point.x <= -1000 ? c.point.x : 0 break
c.state = vc.frame.origin.x <= CGFloat(floor(leftOriginX)) + options.horizontalThreshold || c.point.x <= -1000 ? .Closed : .Opened
if .Closed == c.state { default:break
closeLeftViewContainer(x)
} else {
openLeftViewContainer(x)
}
delegate?.sideNavDidEndLeftPan?(self, container: c)
}
} }
} }
} }
...@@ -436,33 +356,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -436,33 +356,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
// :name: handleLeftTapGesture // :name: handleLeftTapGesture
// //
internal func handleLeftTapGesture(gesture: UIPanGestureRecognizer) { internal func handleLeftTapGesture(gesture: UIPanGestureRecognizer) {
if let c = leftContainer {
delegate?.sideNavDidTapLeft?(self, container: c)
closeLeftViewContainer()
}
}
//
// :name: addShadow
//
private func addShadow(inout viewContainer: UIView?) {
if let vc = viewContainer {
vc.layer.shadowOffset = options.shadowOffset
vc.layer.shadowOpacity = options.shadowOpacity
vc.layer.shadowRadius = options.shadowRadius
vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).CGPath
vc.layer.masksToBounds = false
}
}
//
// :name: removeShadow
//
private func removeShadow(inout viewContainer: UIView?) {
if let vc = viewContainer {
vc.layer.opacity = 1
vc.layer.masksToBounds = true
}
} }
// //
...@@ -510,7 +404,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -510,7 +404,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
// //
// :name: isPointContainedWithinViewController // :name: isPointContainedWithinViewController
// //
private func isPointContainedWithinViewController(inout viewContainer: UIView?, point: CGPoint) -> Bool { private func isPointContainedWithinViewController(inout viewContainer: MaterialView?, point: CGPoint) -> Bool {
if let vc = viewContainer { if let vc = viewContainer {
return CGRectContainsPoint(vc.frame, point) return CGRectContainsPoint(vc.frame, point)
} }
...@@ -521,7 +415,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -521,7 +415,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
// :name: prepareMainContainer // :name: prepareMainContainer
// //
private func prepareMainContainer() { private func prepareMainContainer() {
mainViewContainer = UIView(frame: view.bounds) mainViewContainer = MaterialView(frame: view.bounds)
mainViewContainer!.backgroundColor = MaterialColor.clear mainViewContainer!.backgroundColor = MaterialColor.clear
mainViewContainer!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth] mainViewContainer!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
view.addSubview(mainViewContainer!) view.addSubview(mainViewContainer!)
...@@ -531,11 +425,10 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -531,11 +425,10 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
// :name: prepareBackdropContainer // :name: prepareBackdropContainer
// //
private func prepareBackdropContainer() { private func prepareBackdropContainer() {
backdropViewContainer = UIView(frame: view.bounds) backdropLayer.frame = view.bounds
backdropViewContainer!.backgroundColor = options.backdropBackgroundColor backdropLayer.backgroundColor = options.backdropBackgroundColor.CGColor
backdropViewContainer!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth] backdropLayer.opacity = 0
backdropViewContainer!.layer.opacity = 0 view.layer.addSublayer(backdropLayer)
view.addSubview(backdropViewContainer!)
} }
// //
...@@ -549,33 +442,17 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -549,33 +442,17 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
// //
// :name: prepareContainer // :name: prepareContainer
// //
private func prepareContainer(inout container: SideNavigationViewContainer?, inout viewContainer: UIView?, originX: CGFloat, originY: CGFloat, width: CGFloat, height: CGFloat) { private func prepareContainer(inout viewContainer: MaterialView?, originX: CGFloat, originY: CGFloat, width: CGFloat, height: CGFloat) {
container = SideNavigationViewContainer(state: .Closed, point: CGPointZero, frame: CGRectZero) viewContainer = MaterialView(frame: CGRectMake(originX, originY, width, height))
viewContainer = UIView(frame: CGRectMake(originX, originY, width, height)) viewContainer!.backgroundColor = MaterialColor.red.base
viewContainer!.backgroundColor = MaterialColor.clear
viewContainer!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth] viewContainer!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
view.addSubview(viewContainer!) view.addSubview(viewContainer!)
} }
// //
// :name: prepareContainerToOpen
//
private func prepareContainerToOpen(inout viewController: UIViewController?, inout viewContainer: UIView?, state: SideNavigationViewState) {
addShadow(&viewContainer)
toggleStatusBar(true)
}
//
// :name: prepareContainerToClose
//
private func prepareContainerToClose(inout viewController: UIViewController?, state: SideNavigationViewState) {
toggleStatusBar()
}
//
// :name: prepareContainedViewController // :name: prepareContainedViewController
// //
private func prepareContainedViewController(inout viewContainer: UIView?, inout viewController: UIViewController?) { private func prepareContainedViewController(inout viewContainer: MaterialView?, inout viewController: UIViewController?) {
if let vc = viewController { if let vc = viewController {
if let c = viewContainer { if let c = viewContainer {
addChildViewController(vc) addChildViewController(vc)
......
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