AKSideMenu is a UIKit side menu controller for iOS. It supports left and right menus, pan gestures, menu transitions, content scaling, shadows, fade effects, and optional parallax motion.
- iOS 12.0+
- Swift 5.6+
- UIKit
- ARC
In Xcode, open File > Add Package Dependencies... and use:
https://github.com/dogo/AKSideMenu.git
Or add it to Package.swift:
dependencies: [
.package(url: "https://github.com/dogo/AKSideMenu.git", from: "1.4.7")
],
targets: [
.target(
name: "YourTarget",
dependencies: ["AKSideMenu"]
)
]Add AKSideMenu to your Podfile:
pod 'AKSideMenu'Then run:
pod installAdd AKSideMenu to your Cartfile:
github "dogo/AKSideMenu" "1.4.7"Then run:
carthage update --use-xcframeworksCreate your content controller, optional left and right menu controllers, and make AKSideMenu the root controller.
import AKSideMenu
import UIKit
@main
final class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let window = UIWindow(frame: UIScreen.main.bounds)
let contentViewController = UINavigationController(rootViewController: FirstViewController())
let leftMenuViewController = LeftMenuViewController()
let rightMenuViewController = RightMenuViewController()
let sideMenuViewController = AKSideMenu(
contentViewController: contentViewController,
leftMenuViewController: leftMenuViewController,
rightMenuViewController: rightMenuViewController
)
sideMenuViewController.contentViewShadowEnabled = true
sideMenuViewController.contentViewShadowOpacity = 0.4
sideMenuViewController.contentViewScaleValue = 0.8
window.rootViewController = sideMenuViewController
window.backgroundColor = .white
window.makeKeyAndVisible()
self.window = window
return true
}
}Every child controller can access the nearest side menu controller through sideMenuViewController.
sideMenuViewController?.presentLeftMenuViewController()
sideMenuViewController?.presentRightMenuViewController()
sideMenuViewController?.hideMenuViewController()You can also wire buttons directly in Interface Builder using these IBAction helpers:
@IBAction func presentLeftMenuViewController(_: AnyObject)
@IBAction func presentRightMenuViewController(_: AnyObject)Use setContentViewController(_:animated:) when a menu item should replace the main content.
let nextViewController = UINavigationController(rootViewController: SettingsViewController())
sideMenuViewController?.setContentViewController(nextViewController, animated: true)
sideMenuViewController?.hideMenuViewController()AKSideMenu can instantiate its content and menu controllers directly from storyboard identifiers.
- Add a root view controller to your storyboard.
- Set its class to
AKSideMenuor to your ownAKSideMenusubclass. - Add controllers for the content, left menu, and right menu.
- Set their Storyboard IDs.
- In the Attributes inspector for the side menu controller, set:
contentViewStoryboardIDleftMenuViewStoryboardIDrightMenuViewStoryboardID
You can also configure the controllers manually in a subclass:
import AKSideMenu
import UIKit
final class RootViewController: AKSideMenu {
override func awakeFromNib() {
super.awakeFromNib()
contentViewController = storyboard?.instantiateViewController(withIdentifier: "contentViewController")
leftMenuViewController = storyboard?.instantiateViewController(withIdentifier: "leftMenuViewController")
rightMenuViewController = storyboard?.instantiateViewController(withIdentifier: "rightMenuViewController")
}
}Set the delegate to observe menu presentation, hiding, and gesture-recognizer behavior.
sideMenuViewController.delegate = selfextension RootViewController: AKSideMenuDelegate {
func sideMenu(_ sideMenu: AKSideMenu, willShowMenuViewController menuViewController: UIViewController) {
print("Will show menu")
}
func sideMenu(_ sideMenu: AKSideMenu, didShowMenuViewController menuViewController: UIViewController) {
print("Did show menu")
}
func sideMenu(_ sideMenu: AKSideMenu, willHideMenuViewController menuViewController: UIViewController) {
print("Will hide menu")
}
func sideMenu(_ sideMenu: AKSideMenu, didHideMenuViewController menuViewController: UIViewController) {
print("Did hide menu")
}
func sideMenu(_ sideMenu: AKSideMenu, didRecognizePanGesture recognizer: UIPanGestureRecognizer) {
print("Pan gesture recognized")
}
}Available delegate methods:
optional func sideMenu(_ sideMenu: AKSideMenu, shouldRecognizeGesture recognizer: UIGestureRecognizer, simultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
optional func sideMenu(_ sideMenu: AKSideMenu, gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool
optional func sideMenu(_ sideMenu: AKSideMenu, gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool
optional func sideMenu(_ sideMenu: AKSideMenu, didRecognizePanGesture recognizer: UIPanGestureRecognizer)
optional func sideMenu(_ sideMenu: AKSideMenu, willShowMenuViewController menuViewController: UIViewController)
optional func sideMenu(_ sideMenu: AKSideMenu, didShowMenuViewController menuViewController: UIViewController)
optional func sideMenu(_ sideMenu: AKSideMenu, willHideMenuViewController menuViewController: UIViewController)
optional func sideMenu(_ sideMenu: AKSideMenu, didHideMenuViewController menuViewController: UIViewController)| Property | Default | Description |
|---|---|---|
contentViewController |
nil |
Main controller displayed above the menus. |
leftMenuViewController |
nil |
Controller used as the left menu. |
rightMenuViewController |
nil |
Controller used as the right menu. |
backgroundImage |
nil |
Optional image displayed behind the menu and content containers. |
animationDuration |
0.35 |
Duration used for menu and content animations. |
panGestureEnabled |
true |
Enables or disables pan gesture handling. |
panFromEdge |
true |
Requires the pan gesture to begin near the screen edge. |
panFromEdgeZoneWidth |
20.0 |
Width of the edge zone that starts menu panning. |
panMinimumOpenThreshold |
60.0 |
Minimum pan distance needed to open a menu. |
panGestureLeftEnabled |
true |
Enables pan gestures for the left menu. |
panGestureRightEnabled |
true |
Enables pan gestures for the right menu. |
interactivePopGestureRecognizerEnabled |
true |
Keeps navigation controller interactive pop gestures available when possible. |
scaleContentView |
true |
Scales the content view while a menu is visible. |
contentViewScaleValue |
0.7 |
Scale applied to the content view. |
contentViewFadeOutAlpha |
1.0 |
Alpha applied to the content view while a menu is visible. |
contentViewInLandscapeOffsetCenterX |
30.0 |
Horizontal content offset in landscape. |
contentViewInPortraitOffsetCenterX |
30.0 |
Horizontal content offset in portrait. |
contentViewShadowEnabled |
false |
Enables a shadow around the content view. |
contentViewShadowColor |
.black |
Shadow color for the content view. |
contentViewShadowOffset |
.zero |
Shadow offset for the content view. |
contentViewShadowOpacity |
0.4 |
Shadow opacity for the content view. |
contentViewShadowRadius |
8.0 |
Shadow blur radius for the content view. |
scaleMenuView |
true |
Applies menuViewControllerTransformation before the menu animates in. |
menuViewControllerTransformation |
CGAffineTransform(scaleX: 1.5, y: 1.5) |
Initial menu transform. |
fadeMenuView |
true |
Fades the menu view during presentation and dismissal. |
scaleBackgroundImageView |
true |
Scales the background image before the menu opens. |
backgroundTransformScale |
1.7 |
Scale applied to the background image view. |
parallaxEnabled |
true |
Enables motion-effect parallax. |
parallaxMenuMinimumRelativeValue |
-15 |
Minimum menu parallax value. |
parallaxMenuMaximumRelativeValue |
15 |
Maximum menu parallax value. |
parallaxContentMinimumRelativeValue |
-25 |
Minimum content parallax value. |
parallaxContentMaximumRelativeValue |
25 |
Maximum content parallax value. |
bouncesHorizontally |
true |
Allows horizontal panning past the fully opened menu position. |
menuPreferredStatusBarStyle |
.default |
Preferred status bar style while a menu is visible. |
menuPrefersStatusBarHidden |
false |
Controls status bar visibility while a menu is visible. |
The repository includes sample apps in AKSideMenuExamples:
Simple: programmatic UIKit setup.Storyboard: storyboard-based setup.
Open either example project in Xcode and run the shared scheme.
Ideas, issues, and pull requests are welcome. Please keep changes focused and include an example or test when the behavior changes.
AKSideMenu was inspired by RESideMenu by Roman Efimov.
AKSideMenu is available under the MIT license. See LICENSE for details.

