Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 07f6dff8e8 | |||
| a195757c1d | |||
| 68648ef3f1 | |||
| fec44d0cc2 | |||
| 4da251f6ea | |||
| ddbc431d45 | |||
| 405a3ea56d | |||
| 031e3bcfba | |||
| c08c9a92ec | |||
| f980f558b4 | |||
| b183c95efd | |||
| 110eca43d3 | |||
| 8598050032 |
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ SideMenu is a simple and versatile side menu control written in Swift.
|
||||
|
||||
Check out the example project or this [interactive demo](https://appetize.io/app/64a9v3e6b8c6f53zvn5pnny80m) to see it in action!
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Requirements
|
||||
- [x] iOS 8 or higher
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SideMenu"
|
||||
s.version = "1.0.4"
|
||||
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.
|
||||
@@ -21,7 +21,7 @@ Pod::Spec.new do |s|
|
||||
DESC
|
||||
|
||||
s.homepage = "https://github.com/jonkykong/SideMenu"
|
||||
s.screenshots = [ "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Slide%20Out.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Slide%20In.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Dissolve.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/In%20%2B%20Out.gif" ]
|
||||
s.screenshots = [ "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/SlideOut.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/SlideIn.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Dissolve.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/InOut.gif" ]
|
||||
s.license = 'MIT'
|
||||
s.author = { "jonkykong" => "jonk@jonked.com" }
|
||||
s.source = { :git => "https://github.com/jonkykong/SideMenu.git", :tag => s.version.to_s }
|
||||
|
||||
|
Before Width: | Height: | Size: 438 KiB After Width: | Height: | Size: 438 KiB |
|
Before Width: | Height: | Size: 663 KiB After Width: | Height: | Size: 663 KiB |
|
Before Width: | Height: | Size: 605 KiB After Width: | Height: | Size: 605 KiB |
Reference in New Issue
Block a user