Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 07f6dff8e8 | |||
| a195757c1d | |||
| 68648ef3f1 | |||
| fec44d0cc2 | |||
| 4da251f6ea | |||
| ddbc431d45 | |||
| 405a3ea56d |
@@ -173,18 +173,18 @@ public class SideMenuManager {
|
||||
|
||||
var array = [UIScreenEdgePanGestureRecognizer]()
|
||||
|
||||
if forMenu != .Right {
|
||||
if forMenu != .Left {
|
||||
let leftScreenEdgeGestureRecognizer = UIScreenEdgePanGestureRecognizer()
|
||||
leftScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handlePresentMenuPan(_:)))
|
||||
leftScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handlePresentMenuLeftScreenEdge(_:)))
|
||||
leftScreenEdgeGestureRecognizer.edges = .Left
|
||||
leftScreenEdgeGestureRecognizer.cancelsTouchesInView = true
|
||||
toView.addGestureRecognizer(leftScreenEdgeGestureRecognizer)
|
||||
array.append(leftScreenEdgeGestureRecognizer)
|
||||
}
|
||||
|
||||
if forMenu != .Left {
|
||||
if forMenu != .Right {
|
||||
let rightScreenEdgeGestureRecognizer = UIScreenEdgePanGestureRecognizer()
|
||||
rightScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handlePresentMenuPan(_:)))
|
||||
rightScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handlePresentMenuRightScreenEdge(_:)))
|
||||
rightScreenEdgeGestureRecognizer.edges = .Right
|
||||
rightScreenEdgeGestureRecognizer.cancelsTouchesInView = true
|
||||
toView.addGestureRecognizer(rightScreenEdgeGestureRecognizer)
|
||||
|
||||
@@ -13,6 +13,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
private var presenting = false
|
||||
private var interactive = false
|
||||
private static weak var originalSuperview: UIView?
|
||||
private static var switchMenus = false
|
||||
|
||||
internal static let singleton = SideMenuTransition()
|
||||
internal static var presentDirection: UIRectEdge = .Left;
|
||||
@@ -46,62 +47,71 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
return viewController
|
||||
}
|
||||
|
||||
class func handlePresentMenuLeftScreenEdge(edge: UIScreenEdgePanGestureRecognizer) {
|
||||
SideMenuTransition.presentDirection = .Left
|
||||
handlePresentMenuPan(edge)
|
||||
}
|
||||
|
||||
class func handlePresentMenuRightScreenEdge(edge: UIScreenEdgePanGestureRecognizer) {
|
||||
SideMenuTransition.presentDirection = .Right
|
||||
handlePresentMenuPan(edge)
|
||||
}
|
||||
|
||||
class func handlePresentMenuPan(pan: UIPanGestureRecognizer) {
|
||||
// how much distance have we panned in reference to the parent view?
|
||||
if let view = viewControllerForPresentedMenu != nil ? viewControllerForPresentedMenu?.view : pan.view {
|
||||
let transform = view.transform
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let translation = pan.translationInView(pan.view!)
|
||||
view.transform = transform
|
||||
|
||||
// do some math to translate this to a percentage based value
|
||||
if !singleton.interactive {
|
||||
if translation.x == 0 {
|
||||
return // not sure which way the user is swiping yet, so do nothing
|
||||
}
|
||||
|
||||
if let edge = pan as? UIScreenEdgePanGestureRecognizer {
|
||||
SideMenuTransition.presentDirection = edge.edges == .Left ? .Left : .Right
|
||||
} else {
|
||||
SideMenuTransition.presentDirection = translation.x > 0 ? .Left : .Right
|
||||
}
|
||||
|
||||
if let menuViewController: UINavigationController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController {
|
||||
singleton.interactive = true
|
||||
if let visibleViewController = visibleViewController {
|
||||
visibleViewController.presentViewController(menuViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
guard let view = viewControllerForPresentedMenu != nil ? viewControllerForPresentedMenu?.view : pan.view else {
|
||||
return
|
||||
}
|
||||
|
||||
let transform = view.transform
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let translation = pan.translationInView(pan.view!)
|
||||
view.transform = transform
|
||||
|
||||
// do some math to translate this to a percentage based value
|
||||
if !singleton.interactive {
|
||||
if translation.x == 0 {
|
||||
return // not sure which way the user is swiping yet, so do nothing
|
||||
}
|
||||
|
||||
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? 1 : -1
|
||||
let distance = translation.x / SideMenuManager.menuWidth
|
||||
// now lets deal with different states that the gesture recognizer sends
|
||||
switch (pan.state) {
|
||||
case .Began, .Changed:
|
||||
if pan is UIScreenEdgePanGestureRecognizer {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
} else if distance > 0 && SideMenuTransition.presentDirection == .Right && SideMenuManager.menuLeftNavigationController != nil {
|
||||
SideMenuTransition.presentDirection = .Left
|
||||
singleton.cancelInteractiveTransition()
|
||||
viewControllerForPresentedMenu?.presentViewController(SideMenuManager.menuLeftNavigationController!, animated: true, completion: nil)
|
||||
} else if distance < 0 && SideMenuTransition.presentDirection == .Left && SideMenuManager.menuRightNavigationController != nil {
|
||||
SideMenuTransition.presentDirection = .Right
|
||||
singleton.cancelInteractiveTransition()
|
||||
viewControllerForPresentedMenu?.presentViewController(SideMenuManager.menuRightNavigationController!, animated: true, completion: nil)
|
||||
} else {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
}
|
||||
default:
|
||||
singleton.interactive = false
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let velocity = pan.velocityInView(pan.view!).x * direction
|
||||
view.transform = transform
|
||||
if velocity >= 100 || velocity >= -50 && abs(distance) >= 0.5 {
|
||||
singleton.finishInteractiveTransition()
|
||||
} else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
if !(pan is UIScreenEdgePanGestureRecognizer) {
|
||||
SideMenuTransition.presentDirection = translation.x > 0 ? .Left : .Right
|
||||
}
|
||||
|
||||
if let menuViewController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController,
|
||||
visibleViewController = visibleViewController {
|
||||
singleton.interactive = true
|
||||
visibleViewController.presentViewController(menuViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? 1 : -1
|
||||
let distance = translation.x / SideMenuManager.menuWidth
|
||||
// now lets deal with different states that the gesture recognizer sends
|
||||
switch (pan.state) {
|
||||
case .Began, .Changed:
|
||||
if pan is UIScreenEdgePanGestureRecognizer {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
} else if distance > 0 && SideMenuTransition.presentDirection == .Right && SideMenuManager.menuLeftNavigationController != nil {
|
||||
SideMenuTransition.presentDirection = .Left
|
||||
switchMenus = true
|
||||
singleton.cancelInteractiveTransition()
|
||||
} else if distance < 0 && SideMenuTransition.presentDirection == .Left && SideMenuManager.menuRightNavigationController != nil {
|
||||
SideMenuTransition.presentDirection = .Right
|
||||
switchMenus = true
|
||||
singleton.cancelInteractiveTransition()
|
||||
} else {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
}
|
||||
default:
|
||||
singleton.interactive = false
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let velocity = pan.velocityInView(pan.view!).x * direction
|
||||
view.transform = transform
|
||||
if velocity >= 100 || velocity >= -50 && abs(distance) >= 0.5 {
|
||||
singleton.finishInteractiveTransition()
|
||||
} else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,8 +274,6 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
// animate a change from one viewcontroller to another
|
||||
internal func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
|
||||
|
||||
let statusBarStyle = SideMenuTransition.visibleViewController?.preferredStatusBarStyle()
|
||||
|
||||
// get reference to our fromView, toView and the container view that we should perform the transition in
|
||||
let container = transitionContext.containerView()!
|
||||
if let menuBackgroundColor = SideMenuManager.menuAnimationBackgroundColor {
|
||||
@@ -335,36 +343,44 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
SideMenuTransition.hideMenuStart()
|
||||
}
|
||||
}) { (finished) -> Void in
|
||||
if SideMenuTransition.visibleViewController?.preferredStatusBarStyle() != statusBarStyle {
|
||||
print("Warning: do not change the status bar style while using custom transitions or you risk transitions not properly completing and locking up the UI. See http://www.openradar.me/21961293")
|
||||
}
|
||||
// tell our transitionContext object that we've finished animating
|
||||
if transitionContext.transitionWasCancelled() {
|
||||
let viewControllerForPresentedMenu = SideMenuTransition.viewControllerForPresentedMenu
|
||||
|
||||
if self.presenting {
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
} else {
|
||||
SideMenuTransition.presentMenuComplete()
|
||||
}
|
||||
transitionContext.completeTransition(false)
|
||||
} else {
|
||||
if self.presenting {
|
||||
SideMenuTransition.presentMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
container.addSubview(topView)
|
||||
case .MenuSlideIn, .MenuDissolveIn, .ViewSlideInOut:
|
||||
container.insertSubview(topView, atIndex: 0)
|
||||
}
|
||||
if let statusBarView = SideMenuTransition.statusBarView {
|
||||
container.bringSubviewToFront(statusBarView)
|
||||
}
|
||||
} else {
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
menuView.removeFromSuperview()
|
||||
|
||||
if SideMenuTransition.switchMenus {
|
||||
SideMenuTransition.switchMenus = false
|
||||
viewControllerForPresentedMenu?.presentViewController(SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController! : SideMenuManager.menuRightNavigationController!, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if self.presenting {
|
||||
SideMenuTransition.presentMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
container.addSubview(topView)
|
||||
case .MenuSlideIn, .MenuDissolveIn, .ViewSlideInOut:
|
||||
container.insertSubview(topView, atIndex: 0)
|
||||
}
|
||||
if let statusBarView = SideMenuTransition.statusBarView {
|
||||
container.bringSubviewToFront(statusBarView)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
menuView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
|
||||
### If you like SideMenu, give it a ★ at the top right of its [GitHub](https://github.com/jonkykong/SideMenu) page.
|
||||
### If you like SideMenu, give it a ★ at the top right of this page.
|
||||
|
||||
SideMenu is a simple and versatile side menu control written in Swift.
|
||||
* **It can be implemented in storyboard without a single line of code.**
|
||||
* Three standard animation styles to choose from.
|
||||
* Highly customizable without needing to write tons of custom code.
|
||||
* Supports continuous swiping between each side menu in a single gesture.
|
||||
* Menus can be presented and dismissed the same as any other View Controller since this control uses custom transitions.
|
||||
- [x] **It can be implemented in storyboard without a single line of [code](#code-less-storyboard-implementation).**
|
||||
- [x] Three standard animation styles to choose from.
|
||||
- [x] Highly customizable without needing to write tons of custom code.
|
||||
- [x] Supports continuous swiping between each side menu in a single gesture.
|
||||
- [x] Menus can be presented and dismissed the same as any other View Controller since this control uses custom transitions.
|
||||
|
||||
Check out the example project or this [interactive demo](https://appetize.io/app/64a9v3e6b8c6f53zvn5pnny80m) to see it in action!
|
||||
|
||||
@@ -20,7 +20,7 @@ Check out the example project or this [interactive demo](https://appetize.io/app
|
||||

|
||||
|
||||
## Requirements
|
||||
* iOS 8 or higher
|
||||
- [x] iOS 8 or higher
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SideMenu"
|
||||
s.version = "1.1.1"
|
||||
s.version = "1.1.2"
|
||||
s.summary = "Simple side menu control for iOS in Swift inspired by Facebook. Right and Left sides. No coding required."
|
||||
|
||||
# This description is used to generate tags and improve search results.
|
||||
|
||||
Reference in New Issue
Block a user