Compare commits

...

34 Commits

Author SHA1 Message Date
jonkykong 0a18b99541 Updated README. 2016-09-02 15:07:01 -07:00
jonkykong 7646a77eb5 Updated Podfile, README. 2016-09-02 15:06:49 -07:00
jonkykong a5c0c537cd Updated README. 2016-09-01 01:14:29 -07:00
jonkykong 31ea1081d1 Fix for header generation issue. 2016-09-01 01:07:51 -07:00
jonkykong 19ace50017 Revert formatting changes. 2016-09-01 01:04:55 -07:00
jonkykong b4105f4c70 Merge branch 'pr/55' into 1.2.0
* pr/55:
  Objective-C projects can now use SideMenuManager class when importing SideMenu.
2016-09-01 01:02:21 -07:00
jonkykong 092c873849 Support for user interaction from presenting view controller. 2016-09-01 00:57:54 -07:00
jonkykong 654501a2f5 Fix for rotation causing main view controller sizing problems if transformed. 2016-08-31 19:15:41 -07:00
jonkykong 27561da4dd Merge branch 'pr/56' into 1.2.0
* pr/56:
  Restore 'mainViewController.view.frame' to avoid wrong frame after device rotation Move 'SideMenuTransition.tapView.frame' assigning to end of method
  Maked 'appScreenRect' not internal for access from SideMenuTransition
2016-08-31 18:35:16 -07:00
jonkykong 12dca5922e Support for disabling swipe gestures. 2016-08-31 18:33:15 -07:00
Maximilian Alexander 3fc2e45ac7 ensuring that the handling of gestures happen synchronously and not at different states 2016-08-08 17:47:31 -07:00
Maximilian Alexander 68eb20bd7b ensuring that the handling of gestures are only cancel 2016-08-08 17:47:10 -07:00
Maximilian Alexander da2e6d9476 adding gesture switch 2016-08-08 17:29:21 -07:00
Jon Kent 9dfa9cb3ac Update README.md 2016-08-07 13:13:27 -07:00
Jauzee 2565bad185 Restore 'mainViewController.view.frame' to avoid wrong frame after device rotation
Move 'SideMenuTransition.tapView.frame' assigning to end of method
2016-07-27 11:44:18 +03:00
Jauzee c6ea7979cf Maked 'appScreenRect' not internal for access from SideMenuTransition 2016-07-27 11:34:46 +03:00
James Lukanta 78870237e9 Objective-C projects can now use SideMenuManager class when importing SideMenu. 2016-07-26 19:49:19 -07:00
jonkykong b09d8d558b Reverting README for Github. 2016-07-19 12:30:56 -07:00
jonkykong 0e21162aea Merge tag '1.1.9'
* tag '1.1.9':
  Updated README and pod spec.
  Formatting.
  Fixed crashes with force unwrap values when application returns to foreground
2016-07-19 12:23:56 -07:00
jonkykong 347f476296 Updated README and pod spec. 2016-07-19 12:20:30 -07:00
jonkykong 4828c02cc8 Formatting. 2016-07-19 12:17:37 -07:00
Alexander Kukla 3863fffb7e Fixed crashes with force unwrap values when application returns to foreground 2016-07-18 15:16:19 +03:00
jonkykong a54bb35fde Reversing README for github. 2016-07-14 16:13:55 -07:00
jonkykong 129fd45f5e Merge tag '1.1.8'
* tag '1.1.8':
  Updated pod spec and README for cocoa pods.
  Fix to prevent side menu from responding to user interaction while being animated in or out.
  fix #44
2016-07-14 16:12:56 -07:00
jonkykong cb6b297068 Updated pod spec and README for cocoa pods. 2016-07-14 16:02:53 -07:00
jonkykong 49b5f0c4ab Merge branch 'pr/47' into 1.1.8
* pr/47:
  fix #44
2016-07-14 15:57:10 -07:00
jonkykong 7e1b32733a Fix to prevent side menu from responding to user interaction while being animated in or out. 2016-07-14 15:53:49 -07:00
Ngo Quoc Thang b7a769db31 fix #44 2016-07-13 10:25:01 +03:00
jonkykong a6464d3efa Merge tag '1.1.7'
* tag '1.1.7':
  Removed unneeded declaration.
  Updated pod spec and README for cocoa pods.
  - Refactoring to simplify SideMenuManager logic. - Fix for crashes by preventing side menus from being modified while actively presented.
2016-05-14 01:49:47 -07:00
jonkykong 1e6f192e28 Removed unneeded declaration. 2016-05-14 01:42:19 -07:00
jonkykong 771047f506 Updated pod spec and README for cocoa pods. 2016-05-14 01:37:08 -07:00
jonkykong c8ede5cd76 - Refactoring to simplify SideMenuManager logic.
- Fix for crashes by preventing side menus from being modified while actively presented.
2016-05-14 01:33:17 -07:00
jonkykong 335130ff7a Reversing README for github. 2016-05-02 16:57:04 -07:00
jonkykong 18fdc7f00e Merge tag '1.1.6'
* tag '1.1.6':
  Updates to README and podspec.
2016-05-02 16:56:42 -07:00
6 changed files with 249 additions and 172 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="yAA-s6-Bam">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="yAA-s6-Bam">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+83 -80
View File
@@ -16,17 +16,14 @@
SideMenuManager.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController!.view)
*/
public class SideMenuManager {
public class SideMenuManager : NSObject {
public enum MenuPresentMode {
@objc public enum MenuPresentMode : Int {
case MenuSlideIn
case ViewSlideOut
case ViewSlideInOut
case MenuDissolveIn
}
private static var originalLeftMenuBackgroundColor: UIColor?
private static var originalRightMenuBackgroundColor: UIColor?
// Bounds which has been allocated for the app on the whole device screen
internal static var appScreenRect: CGRect {
@@ -84,13 +81,19 @@ public class SideMenuManager {
/// The right menu swipe to dismiss gesture.
public static weak var menuRightSwipeToDismissGesture: UIPanGestureRecognizer?
/// Enable or disable gestures that would swipe to present or dismiss the menu. Default is true.
public static var menuEnableSwipeGestures: Bool = true
/// Enable or disable interaction with the presenting view controller while the menu is displayed. Enabling may make it difficult to dismiss the menu or cause exceptions if the user tries to present and already presented menu. Default is false.
public static var menuPresentingViewControllerUserInteractionEnabled: Bool = false
/// The strength of the parallax effect on the existing view controller. Does not apply to `menuPresentMode` when set to `ViewSlideOut`. Default is 0.
public static var menuParallaxStrength: Int = 0
/// Draws the `menuAnimationBackgroundColor` behind the status bar. Default is true.
public static var menuFadeStatusBar = true
/// - Warning: Deprecated. Use `menuAnimationTransformScaleFactor` instead.
/// -Warning: Deprecated. Use `menuAnimationTransformScaleFactor` instead.
@available(*, deprecated, renamed="menuAnimationTransformScaleFactor")
public static var menuAnimationShrinkStrength: CGFloat {
get {
@@ -102,7 +105,7 @@ public class SideMenuManager {
}
// prevent instantiation
private init() {}
private override init() {}
/**
The blur effect style of the menu if the menu's root view controller is a UITableViewController or UICollectionViewController.
@@ -111,119 +114,120 @@ public class SideMenuManager {
*/
public static var menuBlurEffectStyle: UIBlurEffectStyle? {
didSet {
updateMenuBlurIfNecessary()
if oldValue != menuBlurEffectStyle {
updateMenuBlurIfNecessary()
}
}
}
/// The left menu.
public static var menuLeftNavigationController: UISideMenuNavigationController? {
willSet {
if menuLeftNavigationController != nil {
let originalBlurEffectStyle = menuBlurEffectStyle
menuBlurEffectStyle = nil
updateMenuBlurIfNecessary()
menuBlurEffectStyle = originalBlurEffectStyle
if menuLeftNavigationController?.presentingViewController == nil {
removeMenuBlurForMenu(menuLeftNavigationController)
}
}
didSet {
if let menuLeftNavigationController = menuLeftNavigationController {
let exitPanGesture = UIPanGestureRecognizer()
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
menuLeftNavigationController.view.addGestureRecognizer(exitPanGesture)
menuLeftNavigationController.transitioningDelegate = SideMenuTransition.singleton
menuLeftNavigationController.modalPresentationStyle = .OverFullScreen
if !menuLeftNavigationController.leftSide {
menuLeftNavigationController.leftSide = true
}
menuLeftSwipeToDismissGesture = exitPanGesture
updateMenuBlurIfNecessary()
guard oldValue?.presentingViewController == nil else {
print("SideMenu Warning: menuLeftNavigationController cannot be modified while it's presented.")
menuLeftNavigationController = oldValue
return
}
setupNavigationController(menuLeftNavigationController, leftSide: true)
}
}
/// The right menu.
public static var menuRightNavigationController: UISideMenuNavigationController? {
willSet {
if menuRightNavigationController != nil {
let originalBlurEffectStyle = menuBlurEffectStyle
menuBlurEffectStyle = nil
updateMenuBlurIfNecessary()
menuBlurEffectStyle = originalBlurEffectStyle
if menuRightNavigationController?.presentingViewController == nil {
removeMenuBlurForMenu(menuRightNavigationController)
}
}
didSet {
if let menuRightNavigationController = menuRightNavigationController {
let exitPanGesture = UIPanGestureRecognizer()
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
menuRightNavigationController.view.addGestureRecognizer(exitPanGesture)
menuRightNavigationController.transitioningDelegate = SideMenuTransition.singleton
menuRightNavigationController.modalPresentationStyle = .OverFullScreen
if menuRightNavigationController.leftSide {
menuRightNavigationController.leftSide = false
}
menuRightSwipeToDismissGesture = exitPanGesture
updateMenuBlurIfNecessary()
guard oldValue?.presentingViewController == nil else {
print("SideMenu Warning: menuRightNavigationController cannot be modified while it's presented.")
menuRightNavigationController = oldValue
return
}
setupNavigationController(menuRightNavigationController, leftSide: false)
}
}
private class func setupNavigationController(forMenu: UISideMenuNavigationController?, leftSide: Bool) {
guard let forMenu = forMenu else {
return
}
let exitPanGesture = UIPanGestureRecognizer()
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
forMenu.view.addGestureRecognizer(exitPanGesture)
forMenu.transitioningDelegate = SideMenuTransition.singleton
forMenu.modalPresentationStyle = .OverFullScreen
forMenu.leftSide = leftSide
if leftSide {
menuLeftSwipeToDismissGesture = exitPanGesture
} else {
menuRightSwipeToDismissGesture = exitPanGesture
}
updateMenuBlurIfNecessary()
}
private class func updateMenuBlurIfNecessary() {
if let menuLeftNavigationController = menuLeftNavigationController, let view = menuLeftNavigationController.visibleViewController?.view {
if !UIAccessibilityIsReduceTransparencyEnabled() && menuBlurEffectStyle != nil {
if originalLeftMenuBackgroundColor == nil {
originalLeftMenuBackgroundColor = view.backgroundColor
}
setupMenuBlurForMenu(menuLeftNavigationController)
} else if originalLeftMenuBackgroundColor != nil {
removeMenuBlurForMenu(menuLeftNavigationController)
view.backgroundColor = originalLeftMenuBackgroundColor!
originalLeftMenuBackgroundColor = nil
let menuBlurBlock = { (forMenu: UISideMenuNavigationController?) in
if let forMenu = forMenu {
setupMenuBlurForMenu(forMenu)
}
}
if let menuRightNavigationController = menuRightNavigationController, let view = menuRightNavigationController.visibleViewController?.view {
if !UIAccessibilityIsReduceTransparencyEnabled() && menuBlurEffectStyle != nil {
if originalRightMenuBackgroundColor == nil {
originalRightMenuBackgroundColor = view.backgroundColor
}
setupMenuBlurForMenu(menuRightNavigationController)
} else if originalRightMenuBackgroundColor != nil {
removeMenuBlurForMenu(menuRightNavigationController)
view.backgroundColor = originalRightMenuBackgroundColor!
originalRightMenuBackgroundColor = nil
}
}
menuBlurBlock(menuLeftNavigationController)
menuBlurBlock(menuRightNavigationController)
}
private class func setupMenuBlurForMenu(forMenu: UINavigationController) {
private class func setupMenuBlurForMenu(forMenu: UISideMenuNavigationController?) {
removeMenuBlurForMenu(forMenu)
guard let forMenu = forMenu,
menuBlurEffectStyle = menuBlurEffectStyle,
view = forMenu.visibleViewController?.view
where !UIAccessibilityIsReduceTransparencyEnabled() else {
return
}
if forMenu.originalMenuBackgroundColor == nil {
forMenu.originalMenuBackgroundColor = view.backgroundColor
}
let blurEffect = UIBlurEffect(style: menuBlurEffectStyle)
let blurView = UIVisualEffectView(effect: blurEffect)
view.backgroundColor = UIColor.clearColor()
if let tableViewController = forMenu.visibleViewController as? UITableViewController {
tableViewController.tableView.backgroundColor = UIColor.clearColor()
let blurEffect = UIBlurEffect(style: menuBlurEffectStyle!)
tableViewController.tableView.backgroundView = UIVisualEffectView(effect: blurEffect)
tableViewController.tableView.backgroundView = blurView
tableViewController.tableView.separatorEffect = UIVibrancyEffect(forBlurEffect: blurEffect)
tableViewController.tableView.reloadData()
} else if let viewController = forMenu.visibleViewController {
viewController.view.backgroundColor = UIColor.clearColor()
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: menuBlurEffectStyle!))
} else {
blurView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
blurView.frame = viewController.view.bounds
viewController.view.insertSubview(blurView, atIndex: 0)
blurView.frame = view.bounds
view.insertSubview(blurView, atIndex: 0)
}
}
private class func removeMenuBlurForMenu(forMenu: UINavigationController) {
private class func removeMenuBlurForMenu(forMenu: UISideMenuNavigationController?) {
guard let forMenu = forMenu,
originalMenuBackgroundColor = forMenu.originalMenuBackgroundColor,
view = forMenu.visibleViewController?.view else {
return
}
view.backgroundColor = originalMenuBackgroundColor
forMenu.originalMenuBackgroundColor = nil
if let tableViewController = forMenu.visibleViewController as? UITableViewController {
tableViewController.tableView.backgroundView = nil
tableViewController.tableView.separatorEffect = nil
tableViewController.tableView.reloadData()
} else if let viewController = forMenu.visibleViewController {
if let blurView = viewController.view.subviews[0] as? UIVisualEffectView {
blurView.removeFromSuperview()
}
} else if let blurView = view.subviews[0] as? UIVisualEffectView {
blurView.removeFromSuperview()
}
}
@@ -236,7 +240,6 @@ public class SideMenuManager {
- Returns: The array of screen edge gestures added to `toView`.
*/
public class func menuAddScreenEdgePanGesturesToPresent(toView toView: UIView, forMenu:UIRectEdge? = nil) -> [UIScreenEdgePanGestureRecognizer] {
var array = [UIScreenEdgePanGestureRecognizer]()
if forMenu != .Right {
+50 -27
View File
@@ -17,7 +17,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
internal static let singleton = SideMenuTransition()
internal static var presentDirection: UIRectEdge = .Left;
internal static weak var tapView: UIView!
internal static weak var tapView: UIView?
internal static weak var statusBarView: UIView?
// prevent instantiation
@@ -58,6 +58,10 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
}
class func handlePresentMenuPan(pan: UIPanGestureRecognizer) {
if !SideMenuManager.menuEnableSwipeGestures {
return
}
// how much distance have we panned in reference to the parent view?
guard let view = viewControllerForPresentedMenu != nil ? viewControllerForPresentedMenu?.view : pan.view else {
return
@@ -121,6 +125,10 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
}
class func handleHideMenuPan(pan: UIPanGestureRecognizer) {
if !SideMenuManager.menuEnableSwipeGestures {
return
}
let translation = pan.translationInView(pan.view!)
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? -1 : 1
let distance = translation.x / SideMenuManager.menuWidth * direction
@@ -153,13 +161,13 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
internal class func hideMenuStart() {
NSNotificationCenter.defaultCenter().removeObserver(SideMenuTransition.singleton)
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController!.view : SideMenuManager.menuRightNavigationController!.view
guard let mainViewController = SideMenuTransition.viewControllerForPresentedMenu,
let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController?.view : SideMenuManager.menuRightNavigationController?.view else {return}
menuView.transform = CGAffineTransformIdentity
mainViewController.view.transform = CGAffineTransformIdentity
mainViewController.view.alpha = 1
SideMenuTransition.tapView.frame = CGRectMake(0, 0, mainViewController.view.frame.width, mainViewController.view.frame.height)
SideMenuTransition.tapView?.frame = CGRectMake(0, 0, mainViewController.view.frame.width, mainViewController.view.frame.height)
menuView.frame.origin.y = 0
menuView.frame.size.width = SideMenuManager.menuWidth
menuView.frame.size.height = mainViewController.view.frame.height
@@ -191,9 +199,12 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
}
internal class func hideMenuComplete() {
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController!.view : SideMenuManager.menuRightNavigationController!.view
SideMenuTransition.tapView.removeFromSuperview()
guard let mainViewController = SideMenuTransition.viewControllerForPresentedMenu,
let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController?.view : SideMenuManager.menuRightNavigationController?.view else {
return
}
SideMenuTransition.tapView?.removeFromSuperview()
SideMenuTransition.statusBarView?.removeFromSuperview()
mainViewController.view.motionEffects.removeAll()
mainViewController.view.layer.shadowOpacity = 0
@@ -205,11 +216,11 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
}
internal class func presentMenuStart(forSize size: CGSize = SideMenuManager.appScreenRect.size) {
guard let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController?.view : SideMenuManager.menuRightNavigationController?.view else {
return
guard let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController?.view : SideMenuManager.menuRightNavigationController?.view,
mainViewController = SideMenuTransition.viewControllerForPresentedMenu else {
return
}
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
menuView.transform = CGAffineTransformIdentity
mainViewController.view.transform = CGAffineTransformIdentity
menuView.frame.size.width = SideMenuManager.menuWidth
@@ -236,7 +247,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
menuView.layer.shadowOpacity = SideMenuManager.menuShadowOpacity
menuView.layer.shadowOffset = CGSizeMake(0, 0)
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? 1 : -1
mainViewController.view.frame.origin.x = direction * (menuView.frame.width)
mainViewController.view.frame = CGRect(x: direction * (menuView.frame.width), y: 0, width: size.width, height: size.height)
mainViewController.view.transform = CGAffineTransformMakeScale(SideMenuManager.menuAnimationTransformScaleFactor, SideMenuManager.menuAnimationTransformScaleFactor)
mainViewController.view.alpha = 1 - SideMenuManager.menuAnimationFadeStrength
@@ -254,8 +265,10 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
internal class func presentMenuComplete() {
NSNotificationCenter.defaultCenter().addObserver(SideMenuTransition.singleton, selector:#selector(SideMenuTransition.applicationDidEnterBackgroundNotification), name: UIApplicationDidEnterBackgroundNotification, object: nil)
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
guard let mainViewController = SideMenuTransition.viewControllerForPresentedMenu else {
return
}
switch SideMenuManager.menuPresentMode {
case .MenuSlideIn, .MenuDissolveIn, .ViewSlideInOut:
if SideMenuManager.menuParallaxStrength != 0 {
@@ -302,15 +315,18 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
// prepare menu items to slide in
if presenting {
let tapView = UIView()
tapView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
let exitPanGesture = UIPanGestureRecognizer()
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
let exitTapGesture = UITapGestureRecognizer()
exitTapGesture.addTarget(SideMenuTransition.self, action: #selector(SideMenuTransition.handleHideMenuTap(_:)))
tapView.addGestureRecognizer(exitPanGesture)
tapView.addGestureRecognizer(exitTapGesture)
SideMenuTransition.tapView = tapView
var tapView: UIView?
if !SideMenuManager.menuPresentingViewControllerUserInteractionEnabled {
tapView = UIView()
tapView!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
let exitPanGesture = UIPanGestureRecognizer()
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
let exitTapGesture = UITapGestureRecognizer()
exitTapGesture.addTarget(SideMenuTransition.self, action: #selector(SideMenuTransition.handleHideMenuTap(_:)))
tapView!.addGestureRecognizer(exitPanGesture)
tapView!.addGestureRecognizer(exitTapGesture)
SideMenuTransition.tapView = tapView
}
SideMenuTransition.originalSuperview = topView.superview
@@ -319,10 +335,14 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
case .ViewSlideOut:
container.addSubview(menuView)
container.addSubview(topView)
topView.addSubview(tapView)
if let tapView = tapView {
topView.addSubview(tapView)
}
case .MenuSlideIn, .MenuDissolveIn, .ViewSlideInOut:
container.addSubview(topView)
container.addSubview(tapView)
if let tapView = tapView {
container.addSubview(tapView)
}
container.addSubview(menuView)
}
@@ -347,10 +367,10 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
UIView.animateWithDuration(duration, delay: 0, options: options, animations: { () -> Void in
if self.presenting {
SideMenuTransition.presentMenuStart() // onstage items: slide in
}
else {
} else {
SideMenuTransition.hideMenuStart()
}
menuView.userInteractionEnabled = false
}) { (finished) -> Void in
// tell our transitionContext object that we've finished animating
if transitionContext.transitionWasCancelled() {
@@ -361,6 +381,8 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
} else {
SideMenuTransition.presentMenuComplete()
}
menuView.userInteractionEnabled = true
transitionContext.completeTransition(false)
if SideMenuTransition.switchMenus {
@@ -373,6 +395,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
if self.presenting {
SideMenuTransition.presentMenuComplete()
menuView.userInteractionEnabled = true
transitionContext.completeTransition(true)
switch SideMenuManager.menuPresentMode {
case .ViewSlideOut:
@@ -9,6 +9,8 @@ import UIKit
public class UISideMenuNavigationController: UINavigationController {
internal var originalMenuBackgroundColor: UIColor?
public override func awakeFromNib() {
super.awakeFromNib()
@@ -21,7 +23,7 @@ public class UISideMenuNavigationController: UINavigationController {
/// Whether the menu appears on the right or left side of the screen. Right is the default.
@IBInspectable public var leftSide:Bool = false {
didSet {
if isViewLoaded() { // suppress warnings
if isViewLoaded() && oldValue != leftSide { // suppress warnings
didSetSide()
}
}
@@ -64,7 +66,11 @@ public class UISideMenuNavigationController: UINavigationController {
case .ViewSlideOut, .ViewSlideInOut:
mainView.superview?.insertSubview(view, belowSubview: mainView)
case .MenuSlideIn, .MenuDissolveIn:
mainView.superview?.insertSubview(view, aboveSubview: SideMenuTransition.tapView)
if let tapView = SideMenuTransition.tapView {
mainView.superview?.insertSubview(view, aboveSubview: tapView)
} else {
mainView.superview?.insertSubview(view, aboveSubview: mainView)
}
}
}
}
@@ -113,44 +119,49 @@ public class UISideMenuNavigationController: UINavigationController {
}
override public func pushViewController(viewController: UIViewController, animated: Bool) {
if let menuViewController: UINavigationController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController {
if let presentingViewController = menuViewController.presentingViewController as? UINavigationController {
// to avoid overlapping dismiss & pop/push calls, create a transaction block where the menu
// is dismissed after showing the appropriate screen
CATransaction.begin()
CATransaction.setCompletionBlock( { () -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
self.visibleViewController?.viewWillAppear(false) // Hack: force selection to get cleared on UITableViewControllers when reappearing using custom transitions
})
UIView.animateWithDuration(SideMenuManager.menuAnimationDismissDuration, animations: { () -> Void in
SideMenuTransition.hideMenuStart()
})
if SideMenuManager.menuAllowPopIfPossible {
for subViewController in presentingViewController.viewControllers {
if subViewController.dynamicType == viewController.dynamicType {
presentingViewController.popToViewController(subViewController, animated: animated)
CATransaction.commit()
return
}
}
guard viewControllers.count > 0 else {
// NOTE: pushViewController is called by init(rootViewController: UIViewController)
// so we must perform the normal super method in this case.
super.pushViewController(viewController, animated: true)
return
}
guard let presentingViewController = presentingViewController as? UINavigationController else {
presentViewController(viewController, animated: animated, completion: nil)
print("SideMenu Warning: cannot push a ViewController from a ViewController without a NavigationController. It will be presented it instead.")
return
}
// to avoid overlapping dismiss & pop/push calls, create a transaction block where the menu
// is dismissed after showing the appropriate screen
CATransaction.begin()
CATransaction.setCompletionBlock( { () -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
self.visibleViewController?.viewWillAppear(false) // Hack: force selection to get cleared on UITableViewControllers when reappearing using custom transitions
})
UIView.animateWithDuration(SideMenuManager.menuAnimationDismissDuration, animations: { () -> Void in
SideMenuTransition.hideMenuStart()
})
if SideMenuManager.menuAllowPopIfPossible {
for subViewController in presentingViewController.viewControllers {
if subViewController.dynamicType == viewController.dynamicType {
presentingViewController.popToViewController(subViewController, animated: animated)
CATransaction.commit()
return
}
if !SideMenuManager.menuAllowPushOfSameClassTwice {
if presentingViewController.viewControllers.last?.dynamicType == viewController.dynamicType {
CATransaction.commit()
return
}
}
presentingViewController.pushViewController(viewController, animated: animated)
CATransaction.commit()
} else {
menuViewController.presentViewController(viewController, animated: animated, completion: nil)
print("Warning: attempted to push a ViewController from a ViewController that doesn't have a NavigationController. It will be presented it instead.")
}
}
if !SideMenuManager.menuAllowPushOfSameClassTwice {
if presentingViewController.viewControllers.last?.dynamicType == viewController.dynamicType {
CATransaction.commit()
return
}
}
presentingViewController.pushViewController(viewController, animated: animated)
CATransaction.commit()
}
}
+66 -26
View File
@@ -3,10 +3,7 @@
[![License](https://img.shields.io/cocoapods/l/SideMenu.svg?style=flat)](http://cocoapods.org/pods/SideMenu)
[![Platform](https://img.shields.io/cocoapods/p/SideMenu.svg?style=flat)](http://cocoapods.org/pods/SideMenu)
## Shameless Requests First
**1. ### If you like SideMenu, give it a ★ at the top right of its [GitHub](https://github.com/jonkykong/SideMenu) page.**
**2. I need an invite to Dribbble to share SideMenu. Invite me: https://dribbble.com/jonkykong**
**If you like SideMenu, give it a ★ at the top right of its [GitHub](https://github.com/jonkykong/SideMenu) page.**
## Overview
@@ -46,6 +43,9 @@ platform :ios, '8.0'
use_frameworks!
pod 'SideMenu'
# For Swift 3, use:
# pod 'SideMenu', :git => 'https://github.com/jonkykong/SideMenu.git', :branch => 'swift3'
```
Then, run the following command:
@@ -97,27 +97,67 @@ That's it.
### Customization
Just type `SideMenuManager.menu...` and code completion will show you everything you can customize (defaults are shown below for reference):
``` swift
menuPresentMode:MenuPresentMode = .ViewSlideOut
menuAllowPushOfSameClassTwice = true
menuAllowPopIfPossible = false
menuWidth: CGFloat = max(round(min(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) * 0.75), 240)
menuAnimationPresentDuration = 0.35
menuAnimationDismissDuration = 0.35
menuAnimationFadeStrength: CGFloat = 0
menuAnimationTransformScaleFactor: CGFloat = 1
menuAnimationBackgroundColor: UIColor? = nil
menuShadowOpacity: Float = 0.5
menuShadowColor = UIColor.blackColor()
menuShadowRadius: CGFloat = 5
menuLeftSwipeToDismissGesture: UIPanGestureRecognizer?
menuRightSwipeToDismissGesture: UIPanGestureRecognizer?
menuParallaxStrength: Int = 0
menuFadeStatusBar = true
menuBlurEffectStyle: UIBlurEffectStyle? = nil // Note: if you want cells in a UITableViewController menu to look good, make them a subclass of UITableViewVibrantCell!
menuLeftNavigationController: UILeftMenuNavigationController? = nil
menuRightNavigationController: UIRightMenuNavigationController? = nil
menuAddScreenEdgePanGesturesToPresent(toView toView: UIView, forMenu:UIRectEdge? = nil) -> [UIScreenEdgePanGestureRecognizer]
menuAddPanGestureToPresent(toView toView: UIView) -> UIPanGestureRecognizer
/**
The presentation mode of the menu.
There are four modes in MenuPresentMode:
- MenuSlideIn: Menu slides in over of the existing view.
- ViewSlideOut: The existing view slides out to reveal the menu.
- ViewSlideInOut: The existing view slides out while the menu slides in.
- MenuDissolveIn: The menu dissolves in over the existing view controller.
*/
public static var menuPresentMode: MenuPresentMode = .ViewSlideOut
/// Prevents the same view controller (or a view controller of the same class) from being pushed more than once. Defaults to true.
public static var menuAllowPushOfSameClassTwice = true
/// Pops to any view controller already in the navigation stack instead of the view controller being pushed if they share the same class. Defaults to false.
public static var menuAllowPopIfPossible = false
/// Width of the menu when presented on screen, showing the existing view controller in the remaining space. Default is 75% of the screen width.
public static var menuWidth: CGFloat = max(round(min((appScreenRect.width), (appScreenRect.height)) * 0.75), 240)
/// Duration of the animation when the menu is presented without gestures. Default is 0.35 seconds.
public static var menuAnimationPresentDuration = 0.35
/// Duration of the animation when the menu is dismissed without gestures. Default is 0.35 seconds.
public static var menuAnimationDismissDuration = 0.35
/// Amount to fade the existing view controller when the menu is presented. Default is 0 for no fade. Set to 1 to fade completely.
public static var menuAnimationFadeStrength: CGFloat = 0
/// The amount to scale the existing view controller or the menu view controller depending on the `menuPresentMode`. Default is 1 for no scaling. Less than 1 will shrink, greater than 1 will grow.
public static var menuAnimationTransformScaleFactor: CGFloat = 1
/// The background color behind menu animations. Depending on the animation settings this may not be visible. If `menuFadeStatusBar` is true, this color is used to fade it. Default is black.
public static var menuAnimationBackgroundColor: UIColor?
/// The shadow opacity around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is 0.5 for 50% opacity.
public static var menuShadowOpacity: Float = 0.5
/// The shadow color around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is black.
public static var menuShadowColor = UIColor.blackColor()
/// The radius of the shadow around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is 5.
public static var menuShadowRadius: CGFloat = 5
/// The left menu swipe to dismiss gesture.
public static weak var menuLeftSwipeToDismissGesture: UIPanGestureRecognizer?
/// The right menu swipe to dismiss gesture.
public static weak var menuRightSwipeToDismissGesture: UIPanGestureRecognizer?
/// Enable or disable gestures that would swipe to present or dismiss the menu. Default is true.
public static var menuEnableSwipeGestures: Bool = true
/// Enable or disable interaction with the presenting view controller while the menu is displayed. Enabling may make it difficult to dismiss the menu or cause exceptions if the user tries to present and already presented menu. Default is false.
public static var menuPresentingViewControllerUserInteractionEnabled: Bool = false
/// The strength of the parallax effect on the existing view controller. Does not apply to `menuPresentMode` when set to `ViewSlideOut`. Default is 0.
public static var menuParallaxStrength: Int = 0
/// Draws the `menuAnimationBackgroundColor` behind the status bar. Default is true.
public static var menuFadeStatusBar = true
```
## Known Issues
@@ -128,7 +168,7 @@ My name is Jon Kent and I'm a freelance iOS designer, developer, and mobile stra
🌎 Web: [http://jonkent.me](http://jonkent.me)
✉️ Email: [contact@jonkent.me](mailto:contact@jonkent.me)
✉️ Email: [contact@jonkent.me](mailto:contact@jonkent.me) **_IMPORTANT: If you're having a problem implementing SideMenu, please open an [issue](https://github.com/jonkykong/SideMenu/issues) instead of emailing me. Thanks!_**
## License
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = "SideMenu"
s.version = "1.1.6"
s.version = "1.2.0"
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.