added iOS source code
[wl-app.git] / iOS / Pods / SideMenu / README.md
1 # ▤ SideMenu
2 [![Version](https://img.shields.io/cocoapods/v/SideMenu.svg?style=flat)](http://cocoapods.org/pods/SideMenu)
3 [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
4 [![License](https://img.shields.io/cocoapods/l/SideMenu.svg?style=flat)](http://cocoapods.org/pods/SideMenu)
5 [![Platform](https://img.shields.io/cocoapods/p/SideMenu.svg?style=flat)](http://cocoapods.org/pods/SideMenu)
6
7 ### If you like SideMenu, give it a ★ at the top right of its [GitHub](https://github.com/jonkykong/SideMenu) page.
8 #### Using SideMenu in your app? [Send](mailto:yo@massappeal.co?subject=SideMenu%20in%20action!) me a link to your app in the app store!
9
10 > Hi, I'm Jon Kent and I am an iOS designer, developer, and mobile strategist. I love coffee and play the drums.
11 > * [**Hire me**](mailto:yo@massappeal.co?subject=Let's%20build%20something%20amazing) to help you make cool stuff. *Note: If you're having a problem with SideMenu, please open an [issue](https://github.com/jonkykong/SideMenu/issues/new) and do not email me.*
12 > * Check out my [website](http://massappeal.co) to see some of my other projects.
13 > * Building and maintaining this free library takes time. Help keep me awake and buy me a coffee ☕️ via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=contact%40jonkent%2eme&lc=US&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted).
14
15 ## Overview
16
17 SideMenu is a simple and versatile side menu control written in Swift.
18 - [x] **It can be implemented in storyboard without a single line of [code](#code-less-storyboard-implementation).**
19 - [x] Four standard animation styles to choose from (there's even a parallax effect if you want to get weird).
20 - [x] Highly customizable without needing to write tons of custom code.
21 - [x] Supports continuous swiping between side menus on boths sides in a single gesture.
22 - [x] Global menu configuration. Set-up once and be done for all screens.
23 - [x] Menus can be presented and dismissed the same as any other view controller since this control uses [custom transitions](https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/CustomizingtheTransitionAnimations.html).
24 - [x] Animations use your view controllers, not snapshots.
25 - [x] Properly handles screen rotation and in-call status bar height changes.
26
27 Check out the example project to see it in action!
28 ### Preview Samples
29 | Slide Out | Slide In | Dissolve | Slide In + Out |
30 | --- | --- | --- | --- |
31 | ![](etc/SlideOut.gif) | ![](etc/SlideIn.gif) | ![](etc/Dissolve.gif) | ![](etc/InOut.gif) |
32
33 ## Requirements
34 - [x] Xcode 9.
35 - [x] Swift 4.
36 - [x] iOS 8 or higher.
37
38 ## Installation
39 ### CocoaPods
40
41 [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:
42
43 ```bash
44 $ gem install cocoapods
45 ```
46
47 To integrate SideMenu into your Xcode project using CocoaPods, specify it in your `Podfile`:
48
49 ```ruby
50 source 'https://github.com/CocoaPods/Specs.git'
51 platform :ios, '8.0'
52 use_frameworks!
53
54 pod 'SideMenu'
55
56 # For Swift 3 (no longer maintained), use:
57 # pod 'SideMenu', '~> 2.3.4'
58 ```
59
60 Then, run the following command:
61
62 ```bash
63 $ pod install
64 ```
65
66 ### Carthage
67
68 [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
69
70 You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
71
72 ```bash
73 $ brew update
74 $ brew install carthage
75 ```
76
77 To integrate SideMenu into your Xcode project using Carthage, specify it in your `Cartfile`:
78
79 ```ogdl
80 github "jonkykong/SideMenu" "master"
81 ```
82
83 ## Usage
84 ### Code-less Storyboard Implementation
85 1. Create a Navigation Controller for a side menu. Set the `Custom Class` of the Navigation Controller to be `UISideMenuNavigationController` in the **Identity Inspector**. Set the `Module` to `SideMenu` (ignore this step if you've manually added SideMenu to your project). Create a Root View Controller for the Navigation Controller (shown as a UITableViewController below). Set up any Triggered Segues you want in that view controller.
86 ![](etc/Screenshot1.png)
87
88 2. Set the `Left Side` property of the `UISideMenuNavigationController` to On if you want it to appear from the left side of the screen, or Off/Default if you want it to appear from the right side.
89 ![](etc/Screenshot2.png)
90
91 3. Add a UIButton or UIBarButton to a view controller that you want to display the menu from. Set that button's Triggered Segues action to modally present the Navigation Controller from step 1.
92 ![](etc/Screenshot3.png)
93
94 That's it. *Note: you can only enable gestures in code.*
95 ### Code Implementation
96 First:
97 ```swift
98 import SideMenu
99 ```
100
101 In your view controller's `viewDidLoad` event, do something like this (**IMPORTANT: If you're seeing a black menu when you use gestures, read this section carefully!**):
102 ``` swift
103 // Define the menus
104 let menuLeftNavigationController = UISideMenuNavigationController(rootViewController: YourViewController)
105 // UISideMenuNavigationController is a subclass of UINavigationController, so do any additional configuration 
106 // of it here like setting its viewControllers. If you're using storyboards, you'll want to do something like:
107 // let menuLeftNavigationController = storyboard!.instantiateViewController(withIdentifier: "LeftMenuNavigationController") as! UISideMenuNavigationController
108 SideMenuManager.default.menuLeftNavigationController = menuLeftNavigationController
109
110 let menuRightNavigationController = UISideMenuNavigationController(rootViewController: YourViewController)
111 // UISideMenuNavigationController is a subclass of UINavigationController, so do any additional configuration
112 // of it here like setting its viewControllers. If you're using storyboards, you'll want to do something like:
113 // let menuRightNavigationController = storyboard!.instantiateViewController(withIdentifier: "RightMenuNavigationController") as! UISideMenuNavigationController
114 SideMenuManager.default.menuRightNavigationController = menuRightNavigationController
115
116 // Enable gestures. The left and/or right menus must be set up above for these to work.
117 // Note that these continue to work on the Navigation Controller independent of the view controller it displays!
118 SideMenuManager.default.menuAddPanGestureToPresent(toView: self.navigationController!.navigationBar)
119 SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController!.view)
120 ```
121 Then from a button, do something like this:
122 ``` swift
123 present(SideMenuManager.default.menuLeftNavigationController!, animated: true, completion: nil)
124
125 // Similarly, to dismiss a menu programmatically, you would do this:
126 dismiss(animated: true, completion: nil)
127 ```
128 That's it.
129 ### Customization
130 #### SideMenuManager
131 Just type ` SideMenuManager.default.menu...` and code completion will show you everything you can customize (for Objective-C, use `SideMenuManager.defaultManager.menu...`). Defaults values are shown below for reference:
132 ``` swift
133 /**
134 The push style of the menu.
135
136 There are six modes in MenuPushStyle:
137 - defaultBehavior: The view controller is pushed onto the stack.
138 - popWhenPossible: If a view controller already in the stack is of the same class as the pushed view controller, the stack is instead popped back to the existing view controller. This behavior can help users from getting lost in a deep navigation stack.
139 - preserve: If a view controller already in the stack is of the same class as the pushed view controller, the existing view controller is pushed to the end of the stack. This behavior is similar to a UITabBarController.
140 - preserveAndHideBackButton: Same as .preserve and back buttons are automatically hidden.
141 - replace: Any existing view controllers are released from the stack and replaced with the pushed view controller. Back buttons are automatically hidden. This behavior is ideal if view controllers require a lot of memory or their state doesn't need to be preserved..
142 - subMenu: Unlike all other behaviors that push using the menu's presentingViewController, this behavior pushes view controllers within the menu.  Use this behavior if you want to display a sub menu.
143 */
144 open var menuPushStyle: MenuPushStyle = .defaultBehavior
145
146 /**
147 The presentation mode of the menu.
148
149 There are four modes in MenuPresentMode:
150 - menuSlideIn: Menu slides in over of the existing view.
151 - viewSlideOut: The existing view slides out to reveal the menu.
152 - viewSlideInOut: The existing view slides out while the menu slides in.
153 - menuDissolveIn: The menu dissolves in over the existing view controller.
154 */
155 open var menuPresentMode: MenuPresentMode = .viewSlideOut
156
157 /// Prevents the same view controller (or a view controller of the same class) from being pushed more than once. Defaults to true.
158 open var menuAllowPushOfSameClassTwice = true
159
160 /**
161 Width of the menu when presented on screen, showing the existing view controller in the remaining space. Default is 75% of the screen width.
162
163 Note that each menu's width can be overridden using the `menuWidth` property on any `UISideMenuNavigationController` instance.
164 */
165 open var menuWidth: CGFloat = max(round(min((appScreenRect.width), (appScreenRect.height)) * 0.75), 240)
166
167 /// Duration of the animation when the menu is presented without gestures. Default is 0.35 seconds.
168 open var menuAnimationPresentDuration: Double = 0.35
169
170 /// Duration of the animation when the menu is dismissed without gestures. Default is 0.35 seconds.
171 open var menuAnimationDismissDuration: Double = 0.35
172
173 /// Duration of the remaining animation when the menu is partially dismissed with gestures. Default is 0.35 seconds.
174 open var menuAnimationCompleteGestureDuration: Double = 0.35
175
176 /// Amount to fade the existing view controller when the menu is presented. Default is 0 for no fade. Set to 1 to fade completely.
177 open var menuAnimationFadeStrength: CGFloat = 0
178
179 /// 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.
180 open var menuAnimationTransformScaleFactor: CGFloat = 1
181
182 /// 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.
183 open var menuAnimationBackgroundColor: UIColor?
184
185 /// The shadow opacity around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is 0.5 for 50% opacity.
186 open var menuShadowOpacity: Float = 0.5
187
188 /// The shadow color around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is black.
189 open var menuShadowColor = UIColor.black
190
191 /// The radius of the shadow around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is 5.
192 open var menuShadowRadius: CGFloat = 5
193
194 /// The left menu swipe to dismiss gesture.
195 open weak var menuLeftSwipeToDismissGesture: UIPanGestureRecognizer?
196
197 /// The right menu swipe to dismiss gesture.
198 open weak var menuRightSwipeToDismissGesture: UIPanGestureRecognizer?
199
200 /// Enable or disable gestures that would swipe to dismiss the menu. Default is true.
201 open var menuEnableSwipeGestures: Bool = true
202
203 /// 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.
204 open var menuPresentingViewControllerUserInteractionEnabled: Bool = false
205
206 /// The strength of the parallax effect on the existing view controller. Does not apply to `menuPresentMode` when set to `ViewSlideOut`. Default is 0.
207 open var menuParallaxStrength: Int = 0
208
209 /// Draws the `menuAnimationBackgroundColor` behind the status bar. Default is true.
210 open var menuFadeStatusBar = true
211
212 /// The animation options when a menu is displayed. Ignored when displayed with a gesture.
213 open var menuAnimationOptions: UIViewAnimationOptions = .curveEaseInOut
214
215 /// The animation spring damping when a menu is displayed. Ignored when displayed with a gesture.
216 open var menuAnimationUsingSpringWithDamping: CGFloat = 1
217
218 /// The animation initial spring velocity when a menu is displayed. Ignored when displayed with a gesture.
219 open var menuAnimationInitialSpringVelocity: CGFloat = 1
220
221 /** 
222 Automatically dismisses the menu when another view is pushed from it.
223
224 Note: to prevent the menu from dismissing when presenting, set modalPresentationStyle = .overFullScreen
225 of the view controller being presented in storyboard or during its initalization.
226 */
227 open var menuDismissOnPush = true
228
229 /// Forces menus to always animate when appearing or disappearing, regardless of a pushed view controller's animation.
230 open var menuAlwaysAnimate = false
231
232 /**
233 The blur effect style of the menu if the menu's root view controller is a UITableViewController or UICollectionViewController.
234
235 - Note: If you want cells in a UITableViewController menu to show vibrancy, make them a subclass of UITableViewVibrantCell and set the `blurEffectStyle` of each cell to SideMenuManager.default.menuBlurEffectStyle.
236 */
237 open var menuBlurEffectStyle: UIBlurEffectStyle?
238
239 /// The left menu.
240 open var menuLeftNavigationController: UISideMenuNavigationController?
241
242 /// The right menu.
243 open var menuRightNavigationController: UISideMenuNavigationController?
244
245 /**
246 Adds screen edge gestures to a view to present a menu.
247
248 - Parameter toView: The view to add gestures to.
249 - Parameter forMenu: The menu (left or right) you want to add a gesture for. If unspecified, gestures will be added for both sides.
250
251 - Returns: The array of screen edge gestures added to `toView`.
252 */
253 @discardableResult open func menuAddScreenEdgePanGesturesToPresent(toView: UIView, forMenu:UIRectEdge? = nil) -> [UIScreenEdgePanGestureRecognizer]
254
255 /**
256 Adds a pan edge gesture to a view to present menus.
257
258 - Parameter toView: The view to add a pan gesture to.
259
260 - Returns: The pan gesture added to `toView`.
261 */
262 @discardableResult open func menuAddPanGestureToPresent(toView: UIView) -> UIPanGestureRecognizer
263 ```
264 #### UISideMenuNavigationController
265 `UISideMenuNavigationController` supports the following customizations and properties:
266 ``` swift
267 /// SideMenuManager instance associated with this menu. Default is `SideMenuManager.default`. This property cannot be changed after the menu has loaded.
268 open weak var sideMenuManager: SideMenuManager! = SideMenuManager.default
269
270 /// Width of the menu when presented on screen, showing the existing view controller in the remaining space. Default is zero. When zero, `sideMenuManager.menuWidth` is used. This property cannot be changed while the isHidden property is false.
271 @IBInspectable open var menuWidth: CGFloat = 0
272
273 /// 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.
274 @IBInspectable open var leftSide: Bool = false
275
276 /// Indicates if the menu is anywhere in the view hierarchy, even if covered by another view controller.
277 open var isHidden: Bool
278 ```
279 #### UISideMenuNavigationControllerDelegate
280 To receive notifications when a menu is displayed from a view controller, have it adhere to the  `UISideMenuNavigationControllerDelegate` protocol:
281 ``` swift
282 extension MyViewController: UISideMenuNavigationControllerDelegate {
283
284     func sideMenuWillAppear(menu: UISideMenuNavigationController, animated: Bool) {
285         print("SideMenu Appearing! (animated: \(animated))")
286     }
287
288     func sideMenuDidAppear(menu: UISideMenuNavigationController, animated: Bool) {
289         print("SideMenu Appeared! (animated: \(animated))")
290     }
291
292     func sideMenuWillDisappear(menu: UISideMenuNavigationController, animated: Bool) {
293         print("SideMenu Disappearing! (animated: \(animated))")
294     }
295
296     func sideMenuDidDisappear(menu: UISideMenuNavigationController, animated: Bool) {
297         print("SideMenu Disappeared! (animated: \(animated))")
298     }
299
300 }
301 ```
302 *Note: setting the  `sideMenuDelegate` property on `UISideMenuNavigationController` is optional. If your view controller adheres to the protocol then the methods will be called automatically.*
303 ### Advanced
304 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:
305 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.
306 ``` swift
307 let customSideMenuManager = SideMenuManager()
308 ```
309 2. Setup and display menus with your custom instance the same as you would with the  `SideMenuManager.default` instance.
310 3. If using Storyboards, subclass your instance of `UISideMenuNavigationController` and set its `sideMenuManager` property to your custom instance. This must be done before `viewDidLoad` is called:
311 ``` swift
312 class MySideMenuNavigationController: UISideMenuNavigationController {
313
314     let customSideMenuManager = SideMenuManager()
315
316     override func awakeFromNib() {
317         super.awakeFromNib()
318
319         sideMenuManager = customSideMenuManager
320     }
321
322 }
323 ```
324 Alternatively, you can set  `sideMenuManager` from the view controller that segues to your UISideMenuNavigationController:
325 ``` swift
326 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
327     if let sideMenuNavigationController = segue.destination as? UISideMenuNavigationController {
328         sideMenuNavigationController.sideMenuManager = customSideMenuManager
329     }
330 }
331 ```
332 *Important: displaying SideMenu instances directly over each other is not supported. Use `menuPushStyle = .subMenu` instead.*
333 ## Known Issues
334 * Issue [#258](https://github.com/jonkykong/SideMenu/issues/258).
335 * 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.
336
337 ## Thank You
338 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!
339
340 ## License
341
342 SideMenu is available under the MIT license. See the LICENSE file for more info.