A customizable, interactive, auto expanding and collapsing side menu for iOS written in Swift.
Here are some of the ways InteractiveSideMenu can be customized:
- Animation duration
- Visible content width
- Content scale
- UIView spring animations
- Animation curves
- Customized animation settings for different orientations
- If you need help or found a bug, please, open an issue.
- If you have a feature request, open an issue.
- If you are ready to contribute, submit a pull request.
- If you like Interactive Side Menu, please, give it a star.
- If you use Interactive Side Menu in your application published to AppStore, send us a link and we'll create the list with applications used our library.
You can find more details into CONTRIBUTING file.
To install using CocoaPods, add the following line to your Podfile:
pod 'InteractiveSideMenu'
Please, don't forget to run pod update command to update your local specs repository during migration from one version to another.
To install using Carthage, add the following line to your Cartfile:
github "handsomecode/InteractiveSideMenu"
For updating help when migrating from v2.x to v3.0, see our migration guide.
To implement your side menu you should subclass the MenuContainerViewController and MenuViewController view controllers.
MenuContainerViewControlleris the main container that hosts the side menu and a content controllerMenuViewControlleris the controller for the side menu
Once your subclasses are set up:
- Set your Host and Menu subclasses in the
InteractiveSideMenuhandler. - (Optional) Setup and customize any transition options.
- (Optional) Setup and customize any content controller presentation options.
- Tell the Menu to select the initial content controller.
import InteractiveSideMenu
class HostViewController: MenuContainerViewController {
override func viewDidLoad() {
super.viewDidLoad()
/// 1) Instantiate menu view controller by identifier.
let menuViewController = SampleMenuViewController.storyboardViewController()
InteractiveSideMenu.shared.setMenuContainerController(self, menuViewController: menuViewController)
/// 2) Set up any custom transition options.
let screenSize: CGRect = UIScreen.main.bounds
let transitionOptions = TransitionOptions(duration: 0.4, visibleContentWidth: screenSize.width / 6)
InteractiveSideMenu.shared.transitionOptions = transitionOptions
/// 3) Change any content item presentation options.
InteractiveSideMenu.shared.currentItemOptions.cornerRadius = 10.0
/// 4) Select the initial content controller.
menuViewController.selectInitialContentController(KittyViewController.storyboardViewController())
}
}The MenuViewController class uses an array of SideItemMenuContent objects to display the menu list and provide the data necessary to create content controllers on-demand.
import InteractiveSideMenu
class SampleMenuViewController: MenuViewController {
override func viewDidLoad() {
super.viewDidLoad()
/// Create the side menu items to be used by the table view.
itemContentControllers = createSideMenuContent()
}
func createSideMenuContent() -> [SideMenuItemContent] {
let kittyContent = SideMenuItemContent(menuTitle: "Kitty", classType: KittyViewController.self)
let tabBarContent = SideMenuItemContent(menuTitle: "Tab Bar", classType: TabBarViewController.self)
let tweakContent = SideMenuItemContent(menuTitle: "Tweak Settings", classType: TweakViewController.self)
return [kittyContent, tabBarContent, tweakContent]
}
}To show the menu, call the showSideMenu() function on the InteractiveSideMenu handler.
To hide the menu, call the closeSideMenu() function on the InteractiveSideMenu handler.
import InteractiveSideMenu
class KittyViewController: UIViewController {
/// Show side menu on menu button click
@IBAction func openMenu(_ sender: UIButton) {
InteractiveSideMenu.shared.showSideMenu()
}
/// Hide side menu on menu button click
@IBAction func closeMenu(_ sender: UIButton) {
InteractiveSideMenu.shared.closeSideMenu()
}
}To show a different content controller from the side menu, pass the new controller to the Menu's selectSideItemContent(_ :) function. This also automatically closes the side menu.
class SampleMenuViewController: MenuViewController {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
/// Using the `itemContentControllers` array, instantiate the controller only when needed.
/// Your instantiation mileage may vary.
let controllerType = itemContentControllers[indexPath.row].classType
let storyboard = UIStoryboard(name: String(describing: controllerType.self), bundle: nil)
guard let controller = storyboard.instantiateInitialViewController() else {
preconditionFailure("Invalid initial view controller")
}
/// Tells the system to change the visible content controller
selectSideItemContent(controller)
}
}To get callbacks when the side menu is open, closed, or in transition, you can conform to InteractiveSideMenuDelegate to be notified when the side menu state changes.
public protocol InteractiveSideMenuDelegate: class {
func interactiveSideMenu(_ sideMenu: InteractiveSideMenu, didChangeMenuState menuState: MenuState)
}To customize transition options for different orientations, override viewWillTransition(to:with:) and update the transitionOptions. This can also be done with trait collections using traitCollectionDidChange(_:)
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
var options = TransitionOptions()
options.duration = size.width < size.height ? 0.4 : 0.6
options.visibleContentWidth = size.width / 6
InteractiveSideMenu.shared.transitionOptions = options
}Check out the Sample project for more details and usage examples.
There is an issue associated with the content controller's view not properly having the safeAreaInsets set. This causes the view's layout to shift when the side menu is closed. The issue appears to be tied to the transitionOptions's contentScale setting. Choosing a value in the range 0.87 - 0.91 causes the safeAreaInsets.top to be set to 0.0. The default value of the library is no longer within this range but be mindful if changing that value for your own application.
- iOS 9.0+
- Xcode 9.x
- Swift 4.0
InteractiveSideMenu is available under the Apache License, Version 2.0. See the LICENSE file for more info.