Compare commits

...

32 Commits

Author SHA1 Message Date
jonkykong 2e684440fc Update README for Cocoapods. 2017-10-31 00:28:19 -07:00
jonkykong 6064d6d5fc Updated podspec. 2017-10-31 00:27:58 -07:00
Lawrence Gimenez d13ed0ea9b Fixed SideMenu.UISideMenuNavigationController crash on init(nibName:bundle:) 2017-10-31 15:06:59 +08:00
jonkykong ef607b3ab2 Update README for Github. 2017-10-28 12:05:27 -07:00
jonkykong 069b974145 Merge tag '3.1.3'
* tag '3.1.3':
  Update README for cocoapods.
  Updated podspec.
  Updated README.
2017-10-28 12:04:53 -07:00
jonkykong 3e452b2a69 Update README for cocoapods. 2017-10-28 11:58:48 -07:00
jonkykong 021fe8cd6a Merge branch 'master' into 3.1.3
* master:
  Exposed delegate to @objc.
  Adding omitted initializer.
  README corrections.
2017-10-28 11:58:01 -07:00
jonkykong fd6ecbbece Updated podspec. 2017-10-28 11:55:43 -07:00
jonkykong 313cda5d69 Updated README. 2017-10-28 11:55:24 -07:00
jonkykong e35a46b075 Exposed delegate to @objc. 2017-10-28 11:52:58 -07:00
jonkykong 3702ecb770 Adding omitted initializer. 2017-10-28 11:52:23 -07:00
jonkykong 893818b582 README corrections. 2017-10-26 18:48:29 -07:00
jonkykong f21ed8965d Revert README for Github. 2017-10-26 18:40:22 -07:00
jonkykong db1cf2a6b6 Merge tag '3.1.2'
* tag '3.1.2':
  Updated podspec.
  Updated README.
  Allow for specifying the sideMenuDelegate, otherwise it discovers it automatically.
  Last commit was incorrect -- but this commit fixes it and includes a work-around for more experience devs who may still want to use default initializer as well as silence some newbie warnings.
  Override of navigation controller default init to prevent new developers from seeing black menus.
  It should be possible now to have the menu slide out even if pushing the new view is not animated itself (animating both can look a bit weird when relying on 'animated' only)
2017-10-26 18:39:49 -07:00
jonkykong a66367d84a Updated podspec. 2017-10-26 18:10:58 -07:00
jonkykong 5f8bdab1dc Updated README. 2017-10-26 18:10:23 -07:00
jonkykong 86f592a20d Support for forcing animated menu dismissal even when pushed view controllers are not animated. 2017-10-26 18:08:43 -07:00
jonkykong dd0a14fa61 Allow for specifying the sideMenuDelegate, otherwise it discovers it automatically. 2017-10-26 17:07:46 -07:00
jonkykong 2ba0ef7453 Last commit was incorrect -- but this commit fixes it and includes a work-around for more experience devs who may still want to use default initializer as well as silence some newbie warnings. 2017-10-24 12:15:41 -07:00
jonkykong 6f57e37129 Override of navigation controller default init to prevent new developers from seeing black menus. 2017-10-24 12:13:06 -07:00
Andreas Hilbert 2af0d86c97 It should be possible now to have the menu slide out even if pushing the new view is not animated itself (animating both can look a bit weird when relying on 'animated' only) 2017-10-19 12:11:20 +02:00
Jon Kent 3dc08de6ec Update README.md 2017-10-17 20:03:10 -07:00
Jon Kent 646f2a8094 Update README.md 2017-10-16 23:18:59 -07:00
Jon Kent ef867ff2b3 Update README.md 2017-10-16 23:18:26 -07:00
jonkykong 49dd185fa7 Updated README for Github. 2017-10-11 14:45:34 -07:00
jonkykong 6a87536f76 Merge tag '3.1.1'
* tag '3.1.1':
  Updated podspec.
  Update README for Cocoapods.
  README correction.
  Better logic for managing UISideMenuNavigationController properties across interface builder and programmatic instantiations.
2017-10-11 14:45:10 -07:00
jonkykong a2f299bb5f Updated podspec. 2017-10-11 14:43:08 -07:00
jonkykong 031f97d770 Update README for Cocoapods. 2017-10-11 14:40:45 -07:00
jonkykong 977f9a5b70 README correction. 2017-10-11 14:39:34 -07:00
jonkykong 3a14516905 Better logic for managing UISideMenuNavigationController properties across interface builder and programmatic instantiations. 2017-10-11 14:39:22 -07:00
jonkykong ddefba9c87 Revert README for Github. 2017-10-10 18:37:00 -07:00
jonkykong d3f59a45a7 Merge tag '3.1'
* tag '3.1':
  Updated README for Cocoapods.
  Updated podspec.
  Update README.md
  Updated README.
  Fix for non-animated dismissal of menu causing a black screen.
  Renamed class and refactored how blurring works in UITableViewVibrantCell.
  Major project update to support multiple SideMenuManager instances beyond the primary instance, if necessary.
  Added isHidden property.
  Support for delegate methods on SideMenu appearing/disappearing.
  Refactor.
  Refactoring.
  Fix for menuDismissOnPush as it was incorrectly applied.
  Fix for regression on enums to objective-C.
2017-10-10 18:36:29 -07:00
4 changed files with 90 additions and 34 deletions
+12
View File
@@ -127,6 +127,9 @@ open class SideMenuManager : NSObject {
*/
open var menuDismissOnPush = true
/// Forces menus to always animate when appearing or disappearing, regardless of a pushed view controller's animation.
open var menuAlwaysAnimate = false
/// Default instance of SideMenuManager.
open static let `default` = SideMenuManager()
internal var transition: SideMenuTransition!
@@ -155,6 +158,7 @@ open class SideMenuManager : NSObject {
guard menuLeftNavigationController != newValue, menuLeftNavigationController?.presentingViewController == nil else {
return
}
menuLeftNavigationController?.locked = false
removeMenuBlurForMenu(menuLeftNavigationController)
}
didSet {
@@ -226,14 +230,18 @@ open class SideMenuManager : NSObject {
forMenu.leftSide = leftSide
if forMenu.sideMenuManager != self {
#if !STFU_SIDEMENU
if forMenu.sideMenuManager?.menuLeftNavigationController == forMenu {
print("SideMenu Warning: \(String(describing: forMenu.self)) was already assigned to the menuLeftNavigationController of \(String(describing: forMenu.sideMenuManager!.self)). When using multiple SideMenuManagers you may want to use new instances of UISideMenuNavigationController instead of existing instances to avoid crashes if the menu is presented more than once.")
} else if forMenu.sideMenuManager?.menuRightNavigationController == forMenu {
print("SideMenu Warning: \(String(describing: forMenu.self)) was already assigned to the menuRightNavigationController of \(String(describing: forMenu.sideMenuManager!.self)). When using multiple SideMenuManagers you may want to use new instances of UISideMenuNavigationController instead of existing instances to avoid crashes if the menu is presented more than once.")
}
#endif
forMenu.sideMenuManager = self
}
forMenu.locked = true
if menuEnableSwipeGestures {
let exitPanGesture = UIPanGestureRecognizer()
forMenu.view.addGestureRecognizer(exitPanGesture)
@@ -340,9 +348,11 @@ open class SideMenuManager : NSObject {
leftScreenEdgeGestureRecognizer.addTarget(transition, action:#selector(SideMenuTransition.handlePresentMenuLeftScreenEdge(_:)))
leftScreenEdgeGestureRecognizer.edges = .left
#if !STFU_SIDEMENU
if menuLeftNavigationController == nil {
print("SideMenu Warning: menuAddScreenEdgePanGesturesToPresent was called before menuLeftNavigationController was set. The gesture will not work without a menu. Use menuAddScreenEdgePanGesturesToPresent(toView:forMenu:) to add gestures for only one menu.")
}
#endif
}
if forMenu != .left {
@@ -350,9 +360,11 @@ open class SideMenuManager : NSObject {
rightScreenEdgeGestureRecognizer.addTarget(transition, action:#selector(SideMenuTransition.handlePresentMenuRightScreenEdge(_:)))
rightScreenEdgeGestureRecognizer.edges = .right
#if !STFU_SIDEMENU
if menuRightNavigationController == nil {
print("SideMenu Warning: menuAddScreenEdgePanGesturesToPresent was called before menuRightNavigationController was set. The gesture will not work without a menu. Use menuAddScreenEdgePanGesturesToPresent(toView:forMenu:) to add gestures for only one menu.")
}
#endif
}
return array
@@ -7,7 +7,7 @@
import UIKit
public protocol UISideMenuNavigationControllerDelegate: class {
@objc public protocol UISideMenuNavigationControllerDelegate: class {
func sideMenuWillAppear(menu: UISideMenuNavigationController, animated: Bool)
func sideMenuDidAppear(menu: UISideMenuNavigationController, animated: Bool)
func sideMenuWillDisappear(menu: UISideMenuNavigationController, animated: Bool)
@@ -24,7 +24,16 @@ extension UIViewController {
open class UISideMenuNavigationController: UINavigationController {
fileprivate weak var temporarySideMenuDelegate: UISideMenuNavigationControllerDelegate?
fileprivate weak var foundDelegate: UISideMenuNavigationControllerDelegate?
fileprivate weak var activeDelegate: UISideMenuNavigationControllerDelegate? {
get {
guard !view.isHidden else {
return nil
}
return sideMenuDelegate ?? foundDelegate ?? findDelegate(forViewController: presentingViewController)
}
}
fileprivate func findDelegate(forViewController: UIViewController?) -> UISideMenuNavigationControllerDelegate? {
if let navigationController = forViewController as? UINavigationController {
return findDelegate(forViewController: navigationController.topViewController)
@@ -36,29 +45,25 @@ open class UISideMenuNavigationController: UINavigationController {
return findDelegate(forViewController: splitViewController.viewControllers.last)
}
temporarySideMenuDelegate = forViewController as? UISideMenuNavigationControllerDelegate
return temporarySideMenuDelegate
foundDelegate = forViewController as? UISideMenuNavigationControllerDelegate
return foundDelegate
}
fileprivate var usingInterfaceBuilder = false
internal var locked = false
internal var originalMenuBackgroundColor: UIColor?
internal var transition: SideMenuTransition {
get {
return sideMenuManager.transition
}
}
internal var sideMenuDelegate: UISideMenuNavigationControllerDelegate? {
get {
guard !view.isHidden else {
return nil
}
return temporarySideMenuDelegate ?? findDelegate(forViewController: presentingViewController)
}
}
/// Delegate for receiving appear and disappear related events. If `nil` the visible view controller that displays a `UISideMenuNavigationController` automatically receives these events.
weak var sideMenuDelegate: UISideMenuNavigationControllerDelegate?
/// SideMenuManager instance associated with this menu. Default is `SideMenuManager.default`. This property cannot be changed after the menu has loaded.
open weak var sideMenuManager: SideMenuManager! = SideMenuManager.default {
didSet {
if isViewLoaded && oldValue != nil {
if locked && oldValue != nil {
print("SideMenu Warning: a menu's sideMenuManager property cannot be changed after it has loaded.")
sideMenuManager = oldValue
}
@@ -69,6 +74,7 @@ open class UISideMenuNavigationController: UINavigationController {
@IBInspectable open var menuWidth: CGFloat = 0 {
didSet {
if !isHidden && oldValue != menuWidth {
print("SideMenu Warning: a menu's width property can only be changed when it is hidden.")
menuWidth = oldValue
}
}
@@ -77,7 +83,7 @@ open class UISideMenuNavigationController: UINavigationController {
/// Whether the menu appears on the right or left side of the screen. Right is the default. This property cannot be changed after the menu has loaded.
@IBInspectable open var leftSide: Bool = false {
didSet {
if isViewLoaded && leftSide != oldValue {
if locked && leftSide != oldValue {
print("SideMenu Warning: a menu's leftSide property cannot be changed after it has loaded.")
leftSide = oldValue
}
@@ -91,13 +97,43 @@ open class UISideMenuNavigationController: UINavigationController {
}
}
#if !STFU_SIDEMENU
// This override prevents newbie developers from creating black/blank menus and opening newbie issues.
// If you would like to remove this override, define STFU_SIDEMENU in the Active Compilation Conditions of your .plist file.
// Sorry for the inconvenience experienced developers :(
@available(*, unavailable, renamed: "init(rootViewController:)")
public init() {
fatalError("init is not available")
}
public override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
}
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
#endif
open override func awakeFromNib() {
super.awakeFromNib()
usingInterfaceBuilder = true
}
override open func viewDidLoad() {
super.viewDidLoad()
if leftSide {
sideMenuManager.menuLeftNavigationController = self
} else {
sideMenuManager.menuRightNavigationController = self
if !locked && usingInterfaceBuilder {
if leftSide {
sideMenuManager.menuLeftNavigationController = self
} else {
sideMenuManager.menuRightNavigationController = self
}
}
}
@@ -107,8 +143,8 @@ open class UISideMenuNavigationController: UINavigationController {
// Dismiss keyboard to prevent weird keyboard animations from occurring during transition
presentingViewController?.view.endEditing(true)
temporarySideMenuDelegate = nil
sideMenuDelegate?.sideMenuWillAppear(menu: self, animated: animated)
foundDelegate = nil
activeDelegate?.sideMenuWillAppear(menu: self, animated: animated)
}
override open func viewDidAppear(_ animated: Bool) {
@@ -124,11 +160,13 @@ open class UISideMenuNavigationController: UINavigationController {
return
}
sideMenuDelegate?.sideMenuDidAppear(menu: self, animated: animated)
activeDelegate?.sideMenuDidAppear(menu: self, animated: animated)
#if !STFU_SIDEMENU
if topViewController == nil {
print("SideMenu Warning: the menu doesn't have a view controller to show! UISideMenuNavigationController needs a view controller to display just like a UINavigationController.")
}
#endif
}
override open func viewWillDisappear(_ animated: Bool) {
@@ -162,16 +200,16 @@ open class UISideMenuNavigationController: UINavigationController {
options: sideMenuManager.menuAnimationOptions,
animations: {
self.transition.hideMenuStart()
self.sideMenuDelegate?.sideMenuWillDisappear(menu: self, animated: animated)
self.activeDelegate?.sideMenuWillDisappear(menu: self, animated: animated)
}) { (finished) -> Void in
self.sideMenuDelegate?.sideMenuDidDisappear(menu: self, animated: animated)
self.activeDelegate?.sideMenuDidDisappear(menu: self, animated: animated)
self.view.isHidden = true
}
return
}
sideMenuDelegate?.sideMenuWillDisappear(menu: self, animated: animated)
activeDelegate?.sideMenuWillDisappear(menu: self, animated: animated)
}
override open func viewDidDisappear(_ animated: Bool) {
@@ -181,11 +219,11 @@ open class UISideMenuNavigationController: UINavigationController {
// the view hierarchy leaving the screen black/empty. This is because the transition moves views within a container
// view, but dismissing without animation removes the container view before the original hierarchy is restored.
// This check corrects that.
if let sideMenuDelegate = sideMenuDelegate as? UIViewController, sideMenuDelegate.view.window == nil {
if let sideMenuDelegate = activeDelegate as? UIViewController, sideMenuDelegate.view.window == nil {
transition.hideMenuStart().hideMenuComplete()
}
sideMenuDelegate?.sideMenuDidDisappear(menu: self, animated: animated)
activeDelegate?.sideMenuDidDisappear(menu: self, animated: animated)
// Clear selecton on UITableViewControllers when reappearing using custom transitions
guard let tableViewController = topViewController as? UITableViewController,
@@ -232,15 +270,17 @@ open class UISideMenuNavigationController: UINavigationController {
return
}
let sideMenuDelegate = self.sideMenuDelegate
temporarySideMenuDelegate = nil
let activeDelegate = self.activeDelegate
foundDelegate = nil
// To avoid overlapping dismiss & pop/push calls, create a transaction block where the menu
// is dismissed after showing the appropriate screen
CATransaction.begin()
if sideMenuManager.menuDismissOnPush {
let animated = animated || sideMenuManager.menuAlwaysAnimate
CATransaction.setCompletionBlock( { () -> Void in
sideMenuDelegate?.sideMenuDidDisappear(menu: self, animated: animated)
activeDelegate?.sideMenuDidDisappear(menu: self, animated: animated)
if !animated {
self.transition.hideMenuStart().hideMenuComplete()
}
@@ -256,7 +296,7 @@ open class UISideMenuNavigationController: UINavigationController {
initialSpringVelocity: sideMenuManager.menuAnimationInitialSpringVelocity,
options: sideMenuManager.menuAnimationOptions,
animations: {
sideMenuDelegate?.sideMenuWillDisappear(menu: self, animated: animated)
activeDelegate?.sideMenuWillDisappear(menu: self, animated: animated)
self.transition.hideMenuStart()
})
UIView.setAnimationsEnabled(areAnimationsEnabled)
+6 -2
View File
@@ -100,7 +100,6 @@ In your view controller's `viewDidLoad` event, do something like this (**IMPORTA
``` swift
// Define the menus
let menuLeftNavigationController = UISideMenuNavigationController(rootViewController: YourViewController)
menuLeftNavigationController.leftSide = true
// UISideMenuNavigationController is a subclass of UINavigationController, so do any additional configuration
// of it here like setting its viewControllers. If you're using storyboards, you'll want to do something like:
// let menuLeftNavigationController = storyboard!.instantiateViewController(withIdentifier: "LeftMenuNavigationController") as! UISideMenuNavigationController
@@ -225,6 +224,9 @@ of the view controller being presented in storyboard or during its initalization
*/
open var menuDismissOnPush = true
/// Forces menus to always animate when appearing or disappearing, regardless of a pushed view controller's animation.
open var menuAlwaysAnimate = false
/**
The blur effect style of the menu if the menu's root view controller is a UITableViewController or UICollectionViewController.
@@ -295,6 +297,7 @@ extension MyViewController: UISideMenuNavigationControllerDelegate {
}
```
*Note: setting the `sideMenuDelegate` property on `UISideMenuNavigationController` is optional. If your view controller adheres to the protocol then the methods will be called automatically.*
### Advanced
For simplicity, `SideMenuManager.default` serves as the primary instance as most projects will only need one menu across all screens. If you need to show a different SideMenu, such as from a modal view controller presented from a previous SideMenu, do the following:
1. Declare a variable containing your custom `SideMenuManager` instance. You may want it to define it globally and configure it in your app delegate if menus will be used on multiple screens.
@@ -326,7 +329,8 @@ override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
```
*Important: displaying SideMenu instances directly over each other is not supported. Use `menuPushStyle = .subMenu` instead.*
## Known Issues
Don't try to change the status bar appearance when presenting a menu. When used with quick gestures/animations, it causes the presentation animation to not complete properly and locks the UI. This was fixed in iOS 9.3. See [radar 21961293](http://www.openradar.me/21961293) for more information.
* Issue [#258](https://github.com/jonkykong/SideMenu/issues/258).
* Don't try to change the status bar appearance when presenting a menu. When used with quick gestures/animations, it causes the presentation animation to not complete properly and locks the UI. This was fixed in iOS 9.3. See [radar 21961293](http://www.openradar.me/21961293) for more information.
## Thank You
A special thank you to everyone that has [contributed](https://github.com/jonkykong/SideMenu/graphs/contributors) to this library to make it better. Your support is appreciated!
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = "SideMenu"
s.version = "3.1"
s.version = "3.1.4"
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.