Skip to content

dogo/AKSideMenu

Repository files navigation

AKSideMenu

Building CocoaPods License Carthage compatible

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.

AKSideMenu screenshot AKSideMenu demo

Requirements

  • iOS 12.0+
  • Swift 5.6+
  • UIKit
  • ARC

Installation

Swift Package Manager

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"]
    )
]

CocoaPods

Add AKSideMenu to your Podfile:

pod 'AKSideMenu'

Then run:

pod install

Carthage

Add AKSideMenu to your Cartfile:

github "dogo/AKSideMenu" "1.4.7"

Then run:

carthage update --use-xcframeworks

Quick Start

Create 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
    }
}

Presenting Menus

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)

Switching Content

Use setContentViewController(_:animated:) when a menu item should replace the main content.

let nextViewController = UINavigationController(rootViewController: SettingsViewController())

sideMenuViewController?.setContentViewController(nextViewController, animated: true)
sideMenuViewController?.hideMenuViewController()

Storyboard Setup

AKSideMenu can instantiate its content and menu controllers directly from storyboard identifiers.

  1. Add a root view controller to your storyboard.
  2. Set its class to AKSideMenu or to your own AKSideMenu subclass.
  3. Add controllers for the content, left menu, and right menu.
  4. Set their Storyboard IDs.
  5. In the Attributes inspector for the side menu controller, set:
    • contentViewStoryboardID
    • leftMenuViewStoryboardID
    • rightMenuViewStoryboardID

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")
    }
}

Delegate

Set the delegate to observe menu presentation, hiding, and gesture-recognizer behavior.

sideMenuViewController.delegate = self
extension 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)

Configuration

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.

Examples

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.

Contributing

Ideas, issues, and pull requests are welcome. Please keep changes focused and include an example or test when the behavior changes.

Credits

AKSideMenu was inspired by RESideMenu by Roman Efimov.

License

AKSideMenu is available under the MIT license. See LICENSE for details.

About

Beautiful iOS side menu library with parallax effect. Written in Swift

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Contributors