Implement Your Own Side Menu (Hamburger Menu) Swift 5.2 Xcode 11



In this post, we will learn how to create Side Menu (Hamburger Menu) or a Navigation Drawer like in Android without using third party library in iOS Swift 5.
This easy tutorial will help you add the popular Hamburger Menu to your apps using Swift 5, Xcode 11 and iOS 13.

We’re open-sourcing our own implementation of a slide menu navigation for iOS, written in Swift 5. The implementation is extremely clean and extensible. We’re also providing a hamburger menu icon, which is tappable and slides the Swift drawer menu out.


Getting Started



This is a sample project with a left slide menu, show user profile, image and some menu with image. the bulk of the setup is completed within the Storyboard.



Creating the Xcode Project


Create a new project under file menu and choose “Single View Application”.



In the next window, fill the textfields and click on finish.



now add a HomeViewController.swift (UIViewController) and add MenuViewController with add tableview in Main.Storyboard.




Now, create a couple of new folders as a  new group, And keep the name as, Extension, Cell or Controller.



Let’s begin with the programming part. Check out the three view controllers to know how this works


HomeViewController- This is the main controller which set Navigation Hamburger menu.

Add the following code inside HomeViewController.



class HomeViewController: UIViewController {
    
    var delegate: MenuDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setNavigation()
    }
    func setNavigation(){
        
         self.navigationItem.title = "HOME"
         self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "menu").withRenderingMode(.alwaysOriginal) , style: .plain, target: self, action: #selector(handleMenu))
    }
    @objc func handleMenu(){
           print("Click On menuHandler")
        delegate?.menuHandler(index: -1)
       }
}


ContainerViewController- This controller will handle the interaction between MenuViewController.swift and HomeController.swift.

Add the following code inside ContainerViewController.


class ContainerViewController: UIViewController {
    
    var menuController : MenuViewController!
    var centerVC :UIViewController!
    var homeVC :HomeViewController!
    var isExpandMenu : Bool = false
    override func viewDidLoad() {
        super.viewDidLoad()
        setHomeFun()
        // Do any additional setup after loading the view.
    }
    func setHomeFun(){
        
        if homeVC == nil {
            homeVC = HomeViewController()
            homeVC.delegate = self
            centerVCUINavigationController(rootViewController: homeVC)
            self.view.addSubview(centerVC.view)
            addChild(centerVC)
            centerVC.didMove(toParent: self)
        }
        
    }
    func setHomeFun(index:Int){
        if (index == 1) {
            configureMenu()
        }
        else  if index == 2{
                homeVC.navigationController?.pushViewController(FirstVC(), animated: true)
        }
        else  if index == 3{
                //Add view controller your requirement
            }
        else{
            configureMenu()
            }
    }
  //Configure the Menu bar
    func configureMenu()  {
        if menuController == nil {
            let storyBoard = UIStoryboard(name: "Main", bundle: nil)
            menuController = storyBoard.instantiateViewController(identifier: "MenuViewController") as? MenuViewController
            menuController.delegate = self
            view.insertSubview(menuController.view , at: 0)  
            addChild(menuController)
            menuController.didMove(toParent: self)
            print("configureMenu called")
        }
    }

    func showMenu(isExpand:Bool){
        if isExpand {
            //open Menu
            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: {
                self.centerVC.view.frame.origin.x = self.centerVC.view.frame.width - 70
            }, completion: nil)
        }else{
             //close Menu
           UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: {
            self.centerVC.view.frame.origin.x = 0
                      }, completion: nil)
        }
    }
}

extension ContainerViewController : MenuDelegate{
    func menuHandler(index: Int) {
        if !isExpandMenu {
            configureMenu()
        }
        isExpandMenu = !isExpandMenu
        showMenu(isExpand: isExpandMenu)
        if index > -1 {
            setHomeFun(index: index)
        }
    }
}

MenuViewController- This controller show all menu in tableView and Particular menu click action.Add the following code inside MenuViewController.



class MenuViewControllerUIViewController {
    var imageHeaderViewImageHeaderView!
    var delegate : MenuDelegate?
    
    @IBOutlet weak var tableViewUITableView!
    var menus : Array = [["txtMenu":"Home""imgMenu":"home"],["txtMenu":"SiteMap""imgMenu":"sitemap"],["txtMenu":"Google Search""imgMenu":"google"],["txtMenu":"About Us""imgMenu":"about"]]
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
      
        tableView.separatorStyle = .none
             
        tableView.register(UINib(nibName: "menuCell", bundle: nil), forCellReuseIdentifier: "menuCell")
        self.imageHeaderView = ImageHeaderView.loadNib()
               self.view.addSubview(self.imageHeaderView)
        self.tableView.tableFooterView = UIView()
        self.tableView.rowHeight = 60
    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.imageHeaderView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 200)//160
        self.view.layoutIfNeeded()
    }

}
extension MenuViewController : UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return menus.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath) asmenuCell
        cell.setData(menus[indexPath.rowas [String :AnyObject])
        return cell
    }
}
extension MenuViewController : UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    delegate?.menuHandler(index: indexPath.row + 1 )

}
}

MenuCell- This is TableViewCell used in MenuViewController.Add the following code inside menuCell.



class menuCell: UITableViewCell {
    
    @IBOutlet weak var imgMenu: UIImageView!
    @IBOutlet weak var txtMenu: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }
    func setData(_ data:[String:AnyObject] ) {
        if let cellTxt = data["txtMenu"] as? String
        {
            self.txtMenu.text = cellTxt

        }
        if let cellImg = data["imgMenu"] as? String
        {
            self.imgMenu.image = UIImage(named: cellImg)

        }
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
    
}

After that, I think you are thinking about MenuDelegateSo let’s have look for this. Now Open Protocols.swift and Programming this file as given below. 



protocol MenuDelegate {
    func menuHandler(index : Int)
}

Compile and Test with different iPhone devices

Now compile and test the app. Open the sidebar menu and tap the menu as Home,SiteMap,Google Search and About Us.


AppCodeZip SideBar Menu 
AppCodeZip SideBar Menu 
AppCodeZip SideBar Menu 




For your complete reference, you can download the 👉 final project from GitHub. As always, leave us comment and share your thought about the tutorial.

I hope this article was helpful to you. So, please share it together with your friends and colleagues using the social buttons below!

Post a Comment

0 Comments