Commit 89089e7f by Daniel Dahan

merged issue-21

parents 50d58ec9 55c12730
...@@ -322,7 +322,7 @@ ...@@ -322,7 +322,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 0640; LastUpgradeCheck = 0640;
ORGANIZATIONNAME = "GraphKit Inc."; ORGANIZATIONNAME = "GraphKit, Inc.";
TargetAttributes = { TargetAttributes = {
963832351B88DFD80015F710 = { 963832351B88DFD80015F710 = {
CreatedOnToolsVersion = 6.4; CreatedOnToolsVersion = 6.4;
......
...@@ -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.6.0</string> <string>1.7.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
......
...@@ -46,18 +46,32 @@ public struct Layout { ...@@ -46,18 +46,32 @@ public struct Layout {
} }
/** /**
:name: expandToParentSize :name: expandToParent
*/ */
public static func expandToParentSize(parent: UIView, child: UIView) { public static func expandToParent(parent: UIView, child: UIView) {
let views: Dictionary<String, AnyObject> = ["child" : child] let views: Dictionary<String, AnyObject> = ["child" : child]
parent.addConstraints(constraint("H:|[child]|", options: nil, metrics: nil, views: views)) parent.addConstraints(constraint("H:|[child]|", options: nil, metrics: nil, views: views))
parent.addConstraints(constraint("V:|[child]|", options: nil, metrics: nil, views: views)) parent.addConstraints(constraint("V:|[child]|", options: nil, metrics: nil, views: views))
} }
/** /**
:name: expandToParentSizeWithPad :name: expandToParentHorizontallyWithPad
*/ */
public static func expandToParentSizeWithPad(parent: UIView, child: UIView, left: CGFloat, bottom: CGFloat, right: CGFloat, top: CGFloat) { public static func expandToParentHorizontallyWithPad(parent: UIView, child: UIView, left: CGFloat, right: CGFloat) {
parent.addConstraints(constraint("H:|-(left)-[child]-(right)-|", options: nil, metrics: ["left": left, "right": right], views: ["child" : child]))
}
/**
:name: expandToParentVerticallyWithPad
*/
public static func expandToParentVerticallyWithPad(parent: UIView, child: UIView, top: CGFloat, bottom: CGFloat) {
parent.addConstraints(constraint("V:|-(top)-[child]-(bottom)-|", options: nil, metrics: ["bottom": bottom, "top": top], views: ["child" : child]))
}
/**
:name: expandToParentWithPad
*/
public static func expandToParentWithPad(parent: UIView, child: UIView, left: CGFloat, bottom: CGFloat, right: CGFloat, top: CGFloat) {
let views: Dictionary<String, AnyObject> = ["child" : child] let views: Dictionary<String, AnyObject> = ["child" : child]
parent.addConstraints(constraint("H:|-(left)-[child]-(right)-|", options: nil, metrics: ["left": left, "right": right], views: views)) parent.addConstraints(constraint("H:|-(left)-[child]-(right)-|", options: nil, metrics: ["left": left, "right": right], views: views))
parent.addConstraints(constraint("V:|-(top)-[child]-(bottom)-|", options: nil, metrics: ["bottom": bottom, "top": top], views: views)) parent.addConstraints(constraint("V:|-(top)-[child]-(bottom)-|", options: nil, metrics: ["bottom": bottom, "top": top], views: views))
......
...@@ -174,7 +174,7 @@ public class MaterialButton : UIButton { ...@@ -174,7 +174,7 @@ public class MaterialButton : UIButton {
backgroundColorView.clipsToBounds = true backgroundColorView.clipsToBounds = true
backgroundColorView.userInteractionEnabled = false backgroundColorView.userInteractionEnabled = false
insertSubview(backgroundColorView, atIndex: 0) insertSubview(backgroundColorView, atIndex: 0)
Layout.expandToParentSize(self, child: backgroundColorView) Layout.expandToParent(self, child: backgroundColorView)
} }
// //
......
...@@ -170,7 +170,7 @@ public class MaterialCard : UIView { ...@@ -170,7 +170,7 @@ public class MaterialCard : UIView {
backgroundColorView.clipsToBounds = true backgroundColorView.clipsToBounds = true
backgroundColorView.userInteractionEnabled = false backgroundColorView.userInteractionEnabled = false
insertSubview(backgroundColorView, atIndex: 0) insertSubview(backgroundColorView, atIndex: 0)
Layout.expandToParentSize(self, child: backgroundColorView) Layout.expandToParent(self, child: backgroundColorView)
} }
// //
......
...@@ -25,13 +25,32 @@ public enum SideNavState { ...@@ -25,13 +25,32 @@ public enum SideNavState {
@objc(SideNavContainer) @objc(SideNavContainer)
public class SideNavContainer : Printable { public class SideNavContainer : Printable {
/**
:name: state
*/
public private(set) var state: SideNavState public private(set) var state: SideNavState
/**
:name: point
*/
public private(set) var point: CGPoint public private(set) var point: CGPoint
/**
:name: frame
*/
public private(set) var frame: CGRect public private(set) var frame: CGRect
/**
:name: description
*/
public var description: String { public var description: String {
let s: String = .Opened == state ? "Opened" : "Closed" let s: String = .Opened == state ? "Opened" : "Closed"
return "(state: \(s), point: \(point), frame: \(frame))" return "(state: \(s), point: \(point), frame: \(frame))"
} }
/**
:name: init
*/
public init(state: SideNavState, point: CGPoint, frame: CGRect) { public init(state: SideNavState, point: CGPoint, frame: CGRect) {
self.state = state self.state = state
self.point = point self.point = point
...@@ -64,33 +83,57 @@ public protocol SideNavDelegate { ...@@ -64,33 +83,57 @@ public protocol SideNavDelegate {
optional func sideNavDidOpenBottomViewContainer(nav: SideNavController, container: SideNavContainer) optional func sideNavDidOpenBottomViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidCloseBottomViewContainer(nav: SideNavController, container: SideNavContainer) optional func sideNavDidCloseBottomViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidTapBottom(nav: SideNavController, container: SideNavContainer) optional func sideNavDidTapBottom(nav: SideNavController, container: SideNavContainer)
// top
optional func sideNavDidBeginTopPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidChangeTopPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidEndTopPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidOpenTopViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidCloseTopViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidTapTop(nav: SideNavController, container: SideNavContainer)
} }
@objc(SideNavController) @objc(SideNavController)
public class SideNavController: UIViewController, UIGestureRecognizerDelegate { public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
/** /**
:name: default options
*/
public struct defaultOptions {
public static var bezelWidth: CGFloat = 48
public static var bezelHeight: CGFloat = 48
public static var containerWidth: CGFloat = 240
public static var containerHeight: CGFloat = 240
public static var defaultAnimationDuration: CGFloat = 0.3
public static var threshold: CGFloat = 48
public static var panningEnabled: Bool = true
}
/**
:name: options :name: options
*/ */
public struct options { public struct options {
public static var shadowOpacity: Float = 0 public static var shadowOpacity: Float = 0
public static var shadowRadius: CGFloat = 0 public static var shadowRadius: CGFloat = 0
public static var shadowOffset: CGSize = CGSizeZero public static var shadowOffset: CGSize = CGSizeZero
public static var contentViewScale: CGFloat = 1 public static var backdropScale: CGFloat = 1
public static var contentViewOpacity: CGFloat = 0.5 public static var backdropOpacity: CGFloat = 0.5
public static var hideStatusBar: Bool = true public static var hideStatusBar: Bool = true
public static var horizontalThreshold: CGFloat = 48 public static var horizontalThreshold: CGFloat = defaultOptions.threshold
public static var verticalThreshold: CGFloat = 48 public static var verticalThreshold: CGFloat = defaultOptions.threshold
public static var backdropBackgroundColor: UIColor = MaterialTheme.black.color public static var backdropBackgroundColor: UIColor = MaterialTheme.black.color
public static var animationDuration: CGFloat = 0.3 public static var animationDuration: CGFloat = defaultOptions.defaultAnimationDuration
public static var leftBezelWidth: CGFloat = 16 public static var leftBezelWidth: CGFloat = defaultOptions.bezelWidth
public static var leftViewContainerWidth: CGFloat = 240 public static var leftViewContainerWidth: CGFloat = defaultOptions.containerWidth
public static var leftPanFromBezel: Bool = true public static var leftPanFromBezel: Bool = defaultOptions.panningEnabled
public static var rightBezelWidth: CGFloat = 16 public static var rightBezelWidth: CGFloat = defaultOptions.bezelWidth
public static var rightViewContainerWidth: CGFloat = 240 public static var rightViewContainerWidth: CGFloat = defaultOptions.containerWidth
public static var rightPanFromBezel: Bool = true public static var rightPanFromBezel: Bool = defaultOptions.panningEnabled
public static var bottomBezelHeight: CGFloat = 48 public static var bottomBezelHeight: CGFloat = defaultOptions.bezelHeight
public static var bottomViewContainerHeight: CGFloat = 240 public static var bottomViewContainerHeight: CGFloat = defaultOptions.containerHeight
public static var bottomPanFromBezel: Bool = true public static var bottomPanFromBezel: Bool = defaultOptions.panningEnabled
public static var topBezelHeight: CGFloat = defaultOptions.bezelHeight
public static var topViewContainerHeight: CGFloat = defaultOptions.containerHeight
public static var topPanFromBezel: Bool = defaultOptions.panningEnabled
} }
/** /**
...@@ -136,6 +179,16 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -136,6 +179,16 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
/** /**
:name: isTopContainerOpened
*/
public var isTopContainerOpened: Bool {
if let c = topViewContainer {
return c.frame.origin.y != topOriginY
}
return false
}
/**
:name: isUserInteractionEnabled :name: isUserInteractionEnabled
*/ */
public var isUserInteractionEnabled: Bool { public var isUserInteractionEnabled: Bool {
...@@ -173,6 +226,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -173,6 +226,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
public private(set) var bottomViewContainer: UIView? public private(set) var bottomViewContainer: UIView?
/** /**
:name: bottomViewContainer
*/
public private(set) var topViewContainer: UIView?
/**
:name: leftContainer :name: leftContainer
*/ */
public private(set) var leftContainer: SideNavContainer? public private(set) var leftContainer: SideNavContainer?
...@@ -188,6 +246,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -188,6 +246,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
public private(set) var bottomContainer: SideNavContainer? public private(set) var bottomContainer: SideNavContainer?
/** /**
:name: topContainer
*/
public private(set) var topContainer: SideNavContainer?
/**
:name: mainViewController :name: mainViewController
*/ */
public var mainViewController: UIViewController? public var mainViewController: UIViewController?
...@@ -208,6 +271,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -208,6 +271,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
public var bottomViewController: UIViewController? public var bottomViewController: UIViewController?
/** /**
:name: topViewController
*/
public var topViewController: UIViewController?
/**
:name: leftPanGesture :name: leftPanGesture
*/ */
public var leftPanGesture: UIPanGestureRecognizer? public var leftPanGesture: UIPanGestureRecognizer?
...@@ -228,6 +296,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -228,6 +296,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
public var bottomTapGesture: UITapGestureRecognizer? public var bottomTapGesture: UITapGestureRecognizer?
/** /**
:name: topTapGesture
*/
public var topTapGesture: UITapGestureRecognizer?
/**
:name: rightPanGesture :name: rightPanGesture
*/ */
public var rightPanGesture: UIPanGestureRecognizer? public var rightPanGesture: UIPanGestureRecognizer?
...@@ -237,6 +310,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -237,6 +310,11 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
*/ */
public var bottomPanGesture: UIPanGestureRecognizer? public var bottomPanGesture: UIPanGestureRecognizer?
/**
:name: rightPanGesture
*/
public var topPanGesture: UIPanGestureRecognizer?
// //
// :name: leftOriginX // :name: leftOriginX
// //
...@@ -258,6 +336,13 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -258,6 +336,13 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
return view.bounds.height return view.bounds.height
} }
//
// :name: topOriginY
//
private var topOriginY: CGFloat {
return -options.topViewContainerHeight
}
/** /**
:name: init :name: init
*/ */
...@@ -308,6 +393,17 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -308,6 +393,17 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
/** /**
:name: init :name: init
*/ */
public convenience init(mainViewController: UIViewController, topViewController: UIViewController) {
self.init()
self.mainViewController = mainViewController
self.topViewController = topViewController
prepareView()
prepareTopView()
}
/**
:name: init
*/
public convenience init(mainViewController: UIViewController, leftViewController: UIViewController, rightViewController: UIViewController) { public convenience init(mainViewController: UIViewController, leftViewController: UIViewController, rightViewController: UIViewController) {
self.init() self.init()
self.mainViewController = mainViewController self.mainViewController = mainViewController
...@@ -336,6 +432,23 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -336,6 +432,23 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
/** /**
:name: init :name: init
*/ */
public convenience init(mainViewController: UIViewController, leftViewController: UIViewController, bottomViewController: UIViewController, rightViewController: UIViewController, topViewController: UIViewController) {
self.init()
self.mainViewController = mainViewController
self.leftViewController = leftViewController
self.bottomViewController = bottomViewController
self.rightViewController = rightViewController
self.topViewController = topViewController
prepareView()
prepareLeftView()
prepareBottomView()
prepareRightView()
prepareTopView()
}
/**
:name: init
*/
public convenience init(mainViewController: UIViewController, bottomViewController: UIViewController, rightViewController: UIViewController) { public convenience init(mainViewController: UIViewController, bottomViewController: UIViewController, rightViewController: UIViewController) {
self.init() self.init()
self.mainViewController = mainViewController self.mainViewController = mainViewController
...@@ -346,6 +459,32 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -346,6 +459,32 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
prepareRightView() prepareRightView()
} }
/**
:name: init
*/
public convenience init(mainViewController: UIViewController, bottomViewController: UIViewController, topViewController: UIViewController) {
self.init()
self.mainViewController = mainViewController
self.bottomViewController = bottomViewController
self.topViewController = topViewController
prepareView()
prepareBottomView()
prepareTopView()
}
/**
:name: init
*/
public convenience init(mainViewController: UIViewController, rightViewController: UIViewController, topViewController: UIViewController) {
self.init()
self.mainViewController = mainViewController
self.rightViewController = rightViewController
self.topViewController = topViewController
prepareView()
prepareRightView()
prepareTopView()
}
// //
// :name: viewDidLoad // :name: viewDidLoad
// //
...@@ -359,11 +498,22 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -359,11 +498,22 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
// //
public override func viewWillLayoutSubviews() { public override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews() super.viewWillLayoutSubviews()
if mainViewController != nil {
prepareContainedViewController(&mainViewContainer, viewController: &mainViewController) prepareContainedViewController(&mainViewContainer, viewController: &mainViewController)
}
if leftViewController != nil {
prepareContainedViewController(&leftViewContainer, viewController: &leftViewController) prepareContainedViewController(&leftViewContainer, viewController: &leftViewController)
}
if rightViewController != nil {
prepareContainedViewController(&rightViewContainer, viewController: &rightViewController) prepareContainedViewController(&rightViewContainer, viewController: &rightViewController)
}
if bottomViewController != nil {
prepareContainedViewController(&bottomViewContainer, viewController: &bottomViewController) prepareContainedViewController(&bottomViewContainer, viewController: &bottomViewController)
} }
if topViewController != nil {
prepareContainedViewController(&topViewContainer, viewController: &topViewController)
}
}
/** /**
:name: toggleLeftViewContainer :name: toggleLeftViewContainer
...@@ -380,6 +530,20 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -380,6 +530,20 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
/** /**
:name: toggleBottomViewContainer
*/
public func toggleBottomViewContainer(velocity: CGFloat = 0) {
isBottomContainerOpened ? closeBottomViewContainer(velocity: velocity) : openBottomViewContainer(velocity: velocity)
}
/**
:name: toggleTopViewContainer
*/
public func toggleTopViewContainer(velocity: CGFloat = 0) {
isTopContainerOpened ? closeTopViewContainer(velocity: velocity) : openTopViewContainer(velocity: velocity)
}
/**
:name: openLeftViewContainer :name: openLeftViewContainer
*/ */
public func openLeftViewContainer(velocity: CGFloat = 0) { public func openLeftViewContainer(velocity: CGFloat = 0) {
...@@ -391,8 +555,8 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -391,8 +555,8 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
options: .CurveEaseInOut, options: .CurveEaseInOut,
animations: { _ in animations: { _ in
vc.frame.origin.x = 0 vc.frame.origin.x = 0
self.backdropViewContainer?.layer.opacity = Float(options.contentViewOpacity) self.backdropViewContainer?.layer.opacity = Float(options.backdropOpacity)
self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.contentViewScale, options.contentViewScale) self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.backdropScale, options.backdropScale)
} }
) { _ in ) { _ in
self.isUserInteractionEnabled = false self.isUserInteractionEnabled = false
...@@ -415,8 +579,8 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -415,8 +579,8 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
options: .CurveEaseInOut, options: .CurveEaseInOut,
animations: { _ in animations: { _ in
vc.frame.origin.x = self.rightOriginX - vc.frame.size.width vc.frame.origin.x = self.rightOriginX - vc.frame.size.width
self.backdropViewContainer?.layer.opacity = Float(options.contentViewOpacity) self.backdropViewContainer?.layer.opacity = Float(options.backdropOpacity)
self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.contentViewScale, options.contentViewScale) self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.backdropScale, options.backdropScale)
} }
) { _ in ) { _ in
self.isUserInteractionEnabled = false self.isUserInteractionEnabled = false
...@@ -428,7 +592,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -428,7 +592,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
/** /**
:name: openRightViewContainer :name: openBottomViewContainer
*/ */
public func openBottomViewContainer(velocity: CGFloat = 0) { public func openBottomViewContainer(velocity: CGFloat = 0) {
if let vc = bottomViewContainer { if let vc = bottomViewContainer {
...@@ -439,8 +603,8 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -439,8 +603,8 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
options: .CurveEaseInOut, options: .CurveEaseInOut,
animations: { _ in animations: { _ in
vc.frame.origin.y = self.bottomOriginY - vc.frame.size.height vc.frame.origin.y = self.bottomOriginY - vc.frame.size.height
self.backdropViewContainer?.layer.opacity = Float(options.contentViewOpacity) self.backdropViewContainer?.layer.opacity = Float(options.backdropOpacity)
self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.contentViewScale, options.contentViewScale) self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.backdropScale, options.backdropScale)
} }
) { _ in ) { _ in
self.isUserInteractionEnabled = false self.isUserInteractionEnabled = false
...@@ -452,6 +616,30 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -452,6 +616,30 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
/** /**
:name: openTopViewContainer
*/
public func openTopViewContainer(velocity: CGFloat = 0) {
if let vc = topViewContainer {
if let c = topContainer {
prepareContainerToOpen(&topViewController, viewContainer: &topViewContainer, state: c.state)
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(fabs(vc.frame.origin.y + topOriginY) / velocity)))),
delay: 0,
options: .CurveEaseInOut,
animations: { _ in
vc.frame.origin.y = self.topOriginY + vc.frame.size.height
self.backdropViewContainer?.layer.opacity = Float(options.backdropOpacity)
self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.backdropScale, options.backdropScale)
}
) { _ in
self.isUserInteractionEnabled = false
}
c.state = .Opened
delegate?.sideNavDidOpenTopViewContainer?(self, container: c)
}
}
}
/**
:name: closeLeftViewContainer :name: closeLeftViewContainer
*/ */
public func closeLeftViewContainer(velocity: CGFloat = 0) { public func closeLeftViewContainer(velocity: CGFloat = 0) {
...@@ -502,7 +690,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -502,7 +690,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
/** /**
:name: closeRightViewContainer :name: closeBottomViewContainer
*/ */
public func closeBottomViewContainer(velocity: CGFloat = 0) { public func closeBottomViewContainer(velocity: CGFloat = 0) {
if let vc = bottomViewContainer { if let vc = bottomViewContainer {
...@@ -526,6 +714,31 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -526,6 +714,31 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
} }
/**
:name: closeBottomViewContainer
*/
public func closeTopViewContainer(velocity: CGFloat = 0) {
if let vc = topViewContainer {
if let c = topContainer {
prepareContainerToClose(&topViewController, state: c.state)
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, fabs(vc.frame.origin.y - topOriginY) / velocity))),
delay: 0,
options: .CurveEaseInOut,
animations: { _ in
vc.frame.origin.y = self.topOriginY
self.backdropViewContainer?.layer.opacity = 0
self.mainViewContainer?.transform = CGAffineTransformMakeScale(1, 1)
}
) { _ in
self.removeShadow(&self.topViewContainer)
self.isUserInteractionEnabled = true
}
c.state = .Closed
delegate?.sideNavDidCloseBottomViewContainer?(self, container: c)
}
}
}
/** /**
:name: switchMainViewController :name: switchMainViewController
...@@ -576,6 +789,18 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -576,6 +789,18 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
} }
/**
:name: switchTopViewController
*/
public func switchTopViewController(viewController: UIViewController, closeTopViewContainerViewContainer: Bool) {
removeViewController(&topViewController)
topViewController = viewController
prepareContainedViewController(&topViewContainer, viewController: &topViewController)
if closeTopViewContainerViewContainer {
closeTopViewContainer()
}
}
// //
// :name: gestureRecognizer // :name: gestureRecognizer
// //
...@@ -589,6 +814,9 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -589,6 +814,9 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
if gestureRecognizer == bottomPanGesture { if gestureRecognizer == bottomPanGesture {
return gesturePanBottomViewController(gestureRecognizer, withTouchPoint: touch.locationInView(view)) return gesturePanBottomViewController(gestureRecognizer, withTouchPoint: touch.locationInView(view))
} }
if gestureRecognizer == topPanGesture {
return gesturePanTopViewController(gestureRecognizer, withTouchPoint: touch.locationInView(view))
}
if gestureRecognizer == leftTapGesture { if gestureRecognizer == leftTapGesture {
return isLeftContainerOpened && !isPointContainedWithinViewController(&leftViewContainer, point: touch.locationInView(view)) return isLeftContainerOpened && !isPointContainedWithinViewController(&leftViewContainer, point: touch.locationInView(view))
} }
...@@ -598,6 +826,9 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -598,6 +826,9 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
if gestureRecognizer == bottomTapGesture { if gestureRecognizer == bottomTapGesture {
return isBottomContainerOpened && !isPointContainedWithinViewController(&bottomViewContainer, point: touch.locationInView(view)) return isBottomContainerOpened && !isPointContainedWithinViewController(&bottomViewContainer, point: touch.locationInView(view))
} }
if gestureRecognizer == topTapGesture {
return isTopContainerOpened && !isPointContainedWithinViewController(&topViewContainer, point: touch.locationInView(view))
}
return true return true
} }
...@@ -634,6 +865,14 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -634,6 +865,14 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
// //
// :name: prepareBottomView
//
internal func prepareTopView() {
prepareContainer(&topContainer, viewContainer: &topViewContainer, originX: 0, originY: topOriginY, width: view.bounds.size.width, height: options.topViewContainerHeight)
prepareTopGestures()
}
//
// :name: addGestures // :name: addGestures
// //
private func addGestures(inout pan: UIPanGestureRecognizer?, panSelector: Selector, inout tap: UITapGestureRecognizer?, tapSelector: Selector) { private func addGestures(inout pan: UIPanGestureRecognizer?, panSelector: Selector, inout tap: UITapGestureRecognizer?, tapSelector: Selector) {
...@@ -667,7 +906,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -667,7 +906,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
// :name: handleLeftPanGesture // :name: handleLeftPanGesture
// //
internal func handleLeftPanGesture(gesture: UIPanGestureRecognizer) { internal func handleLeftPanGesture(gesture: UIPanGestureRecognizer) {
if isRightContainerOpened { return } if isRightContainerOpened || isBottomContainerOpened || isTopContainerOpened { return }
if let vc = leftViewContainer { if let vc = leftViewContainer {
if let c = leftContainer { if let c = leftContainer {
if .Began == gesture.state { if .Began == gesture.state {
...@@ -680,10 +919,10 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -680,10 +919,10 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} else if .Changed == gesture.state { } else if .Changed == gesture.state {
c.point = gesture.translationInView(gesture.view!) c.point = gesture.translationInView(gesture.view!)
let r = (vc.frame.origin.x - leftOriginX) / vc.frame.size.width let r = (vc.frame.origin.x - leftOriginX) / vc.frame.size.width
let s: CGFloat = 1 - (1 - options.contentViewScale) * r let s: CGFloat = 1 - (1 - options.backdropScale) * r
let x: CGFloat = c.frame.origin.x + c.point.x let x: CGFloat = c.frame.origin.x + c.point.x
vc.frame.origin.x = x < leftOriginX ? leftOriginX : x > 0 ? 0 : x vc.frame.origin.x = x < leftOriginX ? leftOriginX : x > 0 ? 0 : x
backdropViewContainer?.layer.opacity = Float(r * options.contentViewOpacity) backdropViewContainer?.layer.opacity = Float(r * options.backdropOpacity)
mainViewContainer?.transform = CGAffineTransformMakeScale(s, s) mainViewContainer?.transform = CGAffineTransformMakeScale(s, s)
delegate?.sideNavDidChangeLeftPan?(self, container: c) delegate?.sideNavDidChangeLeftPan?(self, container: c)
} else { } else {
...@@ -715,7 +954,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -715,7 +954,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
// :name: handleRightPanGesture // :name: handleRightPanGesture
// //
internal func handleRightPanGesture(gesture: UIPanGestureRecognizer) { internal func handleRightPanGesture(gesture: UIPanGestureRecognizer) {
if isLeftContainerOpened { return } if isLeftContainerOpened || isBottomContainerOpened || isTopContainerOpened { return }
if let vc = rightViewContainer { if let vc = rightViewContainer {
if let c = rightContainer { if let c = rightContainer {
if .Began == gesture.state { if .Began == gesture.state {
...@@ -728,12 +967,10 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -728,12 +967,10 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} else if .Changed == gesture.state { } else if .Changed == gesture.state {
c.point = gesture.translationInView(gesture.view!) c.point = gesture.translationInView(gesture.view!)
let r = (rightOriginX - vc.frame.origin.x) / vc.frame.size.width let r = (rightOriginX - vc.frame.origin.x) / vc.frame.size.width
let s: CGFloat = 1 - (1 - options.contentViewScale) * r
let m: CGFloat = rightOriginX - vc.frame.size.width let m: CGFloat = rightOriginX - vc.frame.size.width
let x: CGFloat = c.frame.origin.x + c.point.x let x: CGFloat = c.frame.origin.x + c.point.x
vc.frame.origin.x = x > rightOriginX ? rightOriginX : x < m ? m : x vc.frame.origin.x = x > rightOriginX ? rightOriginX : x < m ? m : x
backdropViewContainer?.layer.opacity = Float(r * options.contentViewOpacity) backdropViewContainer?.layer.opacity = Float(r * options.backdropOpacity)
mainViewContainer?.transform = CGAffineTransformMakeScale(s, s)
delegate?.sideNavDidChangeRightPan?(self, container: c) delegate?.sideNavDidChangeRightPan?(self, container: c)
} else { } else {
c.point = gesture.velocityInView(gesture.view) c.point = gesture.velocityInView(gesture.view)
...@@ -761,38 +998,28 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -761,38 +998,28 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
// //
// :name: handleRightPanGesture // :name: handleBottomPanGesture
// //
internal func handleBottomPanGesture(gesture: UIPanGestureRecognizer) { internal func handleBottomPanGesture(gesture: UIPanGestureRecognizer) {
if isLeftContainerOpened || isRightContainerOpened { return } if isLeftContainerOpened || isRightContainerOpened || isTopContainerOpened { return }
if .Began == gesture.state {
if let vc = bottomViewContainer { if let vc = bottomViewContainer {
if let c = bottomContainer { if let c = bottomContainer {
if .Began == gesture.state {
addShadow(&bottomViewContainer) addShadow(&bottomViewContainer)
toggleStatusBar(hide: true) toggleStatusBar(hide: true)
c.state = isBottomContainerOpened ? .Opened : .Closed c.state = isBottomContainerOpened ? .Opened : .Closed
c.point = gesture.locationInView(view) c.point = gesture.locationInView(view)
c.frame = vc.frame c.frame = vc.frame
delegate?.sideNavDidBeginBottomPan?(self, container: c) delegate?.sideNavDidBeginBottomPan?(self, container: c)
}
}
} else if .Changed == gesture.state { } else if .Changed == gesture.state {
if let vc = bottomViewContainer {
if let c = bottomContainer {
c.point = gesture.translationInView(gesture.view!) c.point = gesture.translationInView(gesture.view!)
let r = (bottomOriginY - vc.frame.origin.y) / vc.frame.size.height let r = (bottomOriginY - vc.frame.origin.y) / vc.frame.size.height
let s: CGFloat = 1 - (1 - options.contentViewScale) * r
let m: CGFloat = bottomOriginY - vc.frame.size.height let m: CGFloat = bottomOriginY - vc.frame.size.height
let y: CGFloat = c.frame.origin.y + c.point.y let y: CGFloat = c.frame.origin.y + c.point.y
vc.frame.origin.y = y > bottomOriginY ? bottomOriginY : y < m ? m : y vc.frame.origin.y = y > bottomOriginY ? bottomOriginY : y < m ? m : y
backdropViewContainer?.layer.opacity = Float(r * options.contentViewOpacity) backdropViewContainer?.layer.opacity = Float(r * options.backdropOpacity)
mainViewContainer?.transform = CGAffineTransformMakeScale(s, s)
delegate?.sideNavDidChangeBottomPan?(self, container: c) delegate?.sideNavDidChangeBottomPan?(self, container: c)
}
}
} else { } else {
if let vc = bottomViewContainer {
if let c = bottomContainer {
c.point = gesture.velocityInView(gesture.view) c.point = gesture.velocityInView(gesture.view)
let y: CGFloat = c.point.y <= -1000 || c.point.y >= 1000 ? c.point.y : 0 let y: CGFloat = c.point.y <= -1000 || c.point.y >= 1000 ? c.point.y : 0
c.state = vc.frame.origin.y >= CGFloat(floor(bottomOriginY) - options.verticalThreshold) || c.point.y >= 1000 ? .Closed : .Opened c.state = vc.frame.origin.y >= CGFloat(floor(bottomOriginY) - options.verticalThreshold) || c.point.y >= 1000 ? .Closed : .Opened
...@@ -818,6 +1045,53 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -818,6 +1045,53 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
// //
// :name: handleTopPanGesture
//
internal func handleTopPanGesture(gesture: UIPanGestureRecognizer) {
if isLeftContainerOpened || isRightContainerOpened || isBottomContainerOpened { return }
if let vc = topViewContainer {
if let c = topContainer {
if .Began == gesture.state {
addShadow(&topViewContainer)
toggleStatusBar(hide: true)
c.state = isTopContainerOpened ? .Opened : .Closed
c.point = gesture.locationInView(view)
c.frame = vc.frame
delegate?.sideNavDidBeginTopPan?(self, container: c)
} else if .Changed == gesture.state {
c.point = gesture.translationInView(gesture.view!)
let r = (topOriginY - vc.frame.origin.y) / vc.frame.size.height
let m: CGFloat = topOriginY + vc.frame.size.height
let y: CGFloat = c.frame.origin.y + c.point.y // increase origin y
vc.frame.origin.y = y < topOriginY ? topOriginY : y < m ? y : m
backdropViewContainer?.layer.opacity = Float(abs(r) * options.backdropOpacity)
delegate?.sideNavDidChangeTopPan?(self, container: c)
} else {
c.point = gesture.velocityInView(gesture.view)
let y: CGFloat = c.point.y <= -1000 || c.point.y >= 1000 ? c.point.y : 0
c.state = vc.frame.origin.y >= CGFloat(floor(topOriginY) + options.verticalThreshold) || c.point.y >= 1000 ? .Opened : .Closed
if .Closed == c.state {
closeTopViewContainer(velocity: y)
} else {
openTopViewContainer(velocity: y)
}
delegate?.sideNavDidEndTopPan?(self, container: c)
}
}
}
}
//
// :name: handleRightTapGesture
//
internal func handleTopTapGesture(gesture: UIPanGestureRecognizer) {
if let c = topContainer {
delegate?.sideNavDidTapTop?(self, container: c)
closeTopViewContainer()
}
}
//
// :name: addShadow // :name: addShadow
// //
private func addShadow(inout viewContainer: UIView?) { private func addShadow(inout viewContainer: UIView?) {
...@@ -890,36 +1164,38 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -890,36 +1164,38 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
// //
// :name: gesturePanTopViewController
//
private func gesturePanTopViewController(gesture: UIGestureRecognizer, withTouchPoint point: CGPoint) -> Bool {
return isTopContainerOpened || options.topPanFromBezel && isTopPointContainedWithinRect(point)
}
//
// :name: isLeftPointContainedWithinRect // :name: isLeftPointContainedWithinRect
// //
private func isLeftPointContainedWithinRect(point: CGPoint) -> Bool { private func isLeftPointContainedWithinRect(point: CGPoint) -> Bool {
var r: CGRect = CGRectZero return CGRectContainsPoint(CGRectMake(0, 0, options.leftBezelWidth, view.bounds.size.height), point)
var t: CGRect = CGRectZero
let w: CGFloat = options.leftBezelWidth
CGRectDivide(view.bounds, &r, &t, w, .MinXEdge)
return CGRectContainsPoint(r, point)
} }
// //
// :name: isRightPointContainedWithinRect // :name: isRightPointContainedWithinRect
// //
private func isRightPointContainedWithinRect(point: CGPoint) -> Bool { private func isRightPointContainedWithinRect(point: CGPoint) -> Bool {
var r: CGRect = CGRectZero return CGRectContainsPoint(CGRectMake(CGRectGetMaxX(view.bounds) - options.rightBezelWidth, 0, options.rightBezelWidth, view.bounds.size.height), point)
var t: CGRect = CGRectZero
let w: CGFloat = rightOriginX - options.rightBezelWidth
CGRectDivide(view.bounds, &t, &r, w, .MinXEdge)
return CGRectContainsPoint(r, point)
} }
// //
// :name: isBottomPointContainedWithinRect // :name: isBottomPointContainedWithinRect
// //
private func isBottomPointContainedWithinRect(point: CGPoint) -> Bool { private func isBottomPointContainedWithinRect(point: CGPoint) -> Bool {
var r: CGRect = CGRectZero return CGRectContainsPoint(CGRectMake(0, CGRectGetMaxY(view.bounds) - options.bottomBezelHeight, view.bounds.size.width, options.bottomBezelHeight), point)
var t: CGRect = CGRectZero }
let h: CGFloat = bottomOriginY - options.bottomBezelHeight
CGRectDivide(view.bounds, &t, &r, h, .MinYEdge) //
return CGRectContainsPoint(r, point) // :name: isTopPointContainedWithinRect
//
private func isTopPointContainedWithinRect(point: CGPoint) -> Bool {
return CGRectContainsPoint(CGRectMake(0, 0, view.bounds.size.width, options.topBezelHeight), point)
} }
// //
...@@ -978,6 +1254,14 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -978,6 +1254,14 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
} }
// //
// :name: prepareBottomGestures
//
private func prepareTopGestures() {
removeGestures(&topPanGesture, tap: &topTapGesture)
addGestures(&topPanGesture, panSelector: "handleTopPanGesture:", tap: &topTapGesture, tapSelector: "handleTopTapGesture:")
}
//
// :name: prepareContainer // :name: prepareContainer
// //
private func prepareContainer(inout container: SideNavContainer?, inout viewContainer: UIView?, originX: CGFloat, originY: CGFloat, width: CGFloat, height: CGFloat) { private func prepareContainer(inout container: SideNavContainer?, inout viewContainer: UIView?, originX: CGFloat, originY: CGFloat, width: CGFloat, height: CGFloat) {
...@@ -1017,7 +1301,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate { ...@@ -1017,7 +1301,7 @@ public class SideNavController: UIViewController, UIGestureRecognizerDelegate {
vc.view.setTranslatesAutoresizingMaskIntoConstraints(false) vc.view.setTranslatesAutoresizingMaskIntoConstraints(false)
addChildViewController(vc) addChildViewController(vc)
c.addSubview(vc.view) c.addSubview(vc.view)
Layout.expandToParentSize(c, child: vc.view) Layout.expandToParent(c, child: vc.view)
vc.didMoveToParentViewController(self) vc.didMoveToParentViewController(self)
} }
} }
......
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