Skip to content

Instantly share code, notes, and snippets.

@florianldt
Created November 9, 2019 17:31
Show Gist options
  • Save florianldt/509af4e6f8ee3898822f8f676d378dd1 to your computer and use it in GitHub Desktop.
Save florianldt/509af4e6f8ee3898822f8f676d378dd1 to your computer and use it in GitHub Desktop.
Simple implementation of a side menu using a UIView.
// Simple implementation of a side menu using a UIView.
// I would rather use a new controller to build that menu and add it as a child to this one using the addChild(_ childController: UIViewController) method, but out of scope here.
import UIKit
import PlaygroundSupport
class SideMenuViewController: UIViewController {
private var menuBarButtonItem: UIBarButtonItem!
private let sideMenu: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = UIColor.black.withAlphaComponent(0.4)
return view
}()
private var isMenuShowing: Bool = false {
willSet {
animateMenu(newValue)
handleMenuBarButtonItemTitle(newValue)
}
}
var sideMenuLeftConstraint: NSLayoutConstraint!
enum SideMenuSettings {
static let width: CGFloat = 200
static let animationTime = 0.3
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Side Menu"
view.backgroundColor = .white
setupNavigationBar()
setupViews()
}
private func setupNavigationBar() {
menuBarButtonItem = UIBarButtonItem(title: nil, style: .done, target: self, action: #selector(handleMenu))
navigationItem.leftBarButtonItem = menuBarButtonItem
handleMenuBarButtonItemTitle(isMenuShowing)
}
private func handleMenuBarButtonItemTitle(_ isShowing: Bool) {
let title = isShowing ? "Close" : "Open"
menuBarButtonItem.title = title
}
private func setupViews() {
view.addSubview(sideMenu)
sideMenuLeftConstraint = sideMenu.leftAnchor.constraint(equalTo: view.leftAnchor, constant: -SideMenuSettings.width)
NSLayoutConstraint.activate([
sideMenu.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
sideMenuLeftConstraint,
sideMenu.bottomAnchor.constraint(equalTo: view.bottomAnchor),
sideMenu.widthAnchor.constraint(equalToConstant: SideMenuSettings.width),
])
}
@objc
public func handleMenu() {
isMenuShowing.toggle()
}
private func animateMenu(_ isShowing: Bool) {
sideMenuLeftConstraint.constant = isShowing ? 0 : -SideMenuSettings.width
UIView.animate(withDuration: SideMenuSettings.animationTime,
delay: 0,
options: .curveEaseOut,
animations: {
self.view.layoutIfNeeded()
})
}
}
let viewController = UINavigationController(rootViewController: SideMenuViewController())
PlaygroundPage.current.liveView = viewController
PlaygroundPage.current.needsIndefiniteExecution = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment