如何在Swift3中将视图控制器用作侧面菜单

我正在尝试以编程方式在我的应用程序中实现侧面菜单。 所以我设计了一个视图控制器,其视图的一半作为表视图。 设计和编码完成后,现在我希望将此视图控制器用作侧面菜单控制器。 我的SideMenu故事板是:

在此处输入图像描述

现在我的代码看起来像这样:

import UIKit class SideBarViewController: UIViewController { @IBOutlet weak var menu: UIView! @IBOutlet weak var menuTableView: UITableView! var fieldImages = [UIImage]() var isFirstSectionHidden: Bool = true var isSecondSectionHidden: Bool = true var selectedIndex: Int = 0 var menuTag: Int = 0 var name = "" var email = "" var imageURL = "" var language = "English" var accountNames: [String] = ["My Subscriptions", "My Proposals","My Interests"] var languageNames: [String] = ["English", "Arabic", "Malayalam"] override func viewDidLoad() { super.viewDidLoad() selectedIndex = -1 self.menu.isHidden = true menuTag = 0 // self.profile() let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture)) swipeRight.direction = UISwipeGestureRecognizerDirection.right self.view.addGestureRecognizer(swipeRight) let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture)) swipeLeft.direction = UISwipeGestureRecognizerDirection.left self.view.addGestureRecognizer(swipeLeft) self.fieldImages.append(UIImage(named: "my_subscription_icon")!) self.fieldImages.append(UIImage(named: "my_proposal_icon")!) self.fieldImages.append(UIImage(named: "my_interest_icon")!) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func respondToSwipeGesture(gesture: UIGestureRecognizer) { if let swipeGesture = gesture as? UISwipeGestureRecognizer { switch swipeGesture.direction { case UISwipeGestureRecognizerDirection.right: menuAction() print("Swiped right") case UISwipeGestureRecognizerDirection.left: menuAction() print("Swiped left") default: break } } } func menuAction() { if menuTag == 0 { UIView.animate(withDuration: 0.5, animations: {() -> Void in self.menu.frame = CGRect(x: 0, y: 0, width: self.menu.frame.size.width, height: self.menu.frame.size.height) self.menu.isHidden = false self.menuTag = 1 self.menuTableView.reloadData() }) } else { UIView.animate(withDuration: 0.5, animations: {() -> Void in self.menu.frame = CGRect(x: -self.menu.frame.size.width, y: 0, width: self.menu.frame.size.width, height: self.menu.frame.size.height) self.menu.isHidden = true self.menuTag = 0 self.menuTableView.reloadData() }) selectedIndex = -1 } } func profile() { if Utility.isConnectedToInternet { Utility.startActivityIdicator() VanpoolAPI.profile { (response) in Utility.stopActivityIndicator() if response == nil { Utility.showAlert(title: Constants.error, message: Constants.someThingWrong, delegate: self) } else { if response?.status == ResponseCode.success.code { self.name = (response?.name)! self.email = (response?.email)! self.imageURL = (response?.displayPictureUrl)! } else { Utility.showAlert(title:Constants.appName, message:response?.message?.key ?? "", delegate: self) } } } } else { Utility.showAlert(title: Constants.appName, message: Constants.noNetwork, delegate: self) } } func logout() { if Utility.isConnectedToInternet { Utility.startActivityIdicator() VanpoolAPI.logout { (response) in Utility.stopActivityIndicator() if response == nil { Utility.showAlert(title: Constants.error, message: Constants.someThingWrong, delegate: self) } else { if response?.status == ResponseCode.success.code { } else { Utility.showAlert(title:Constants.appName, message:response?.message?.key ?? "", delegate: self) } } } } else { Utility.showAlert(title: Constants.appName, message: Constants.noNetwork, delegate: self) } } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destinationViewController. // Pass the selected object to the new view controller. } */ } extension SideBarViewController: UITableViewDelegate, UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 11 } // number of rows in table view func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if section == 0 { return 1 } else if selectedIndex == section { return 3 } else { return 0 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cell = UITableViewCell() switch indexPath.section { case 0: let cellProfile = (menuTableView.dequeueReusableCell(withIdentifier:"profileCell", for: indexPath)as? MenuTableViewCell)! cellProfile.profile.layer.masksToBounds = false cellProfile.profile.layer.cornerRadius = cellProfile.profile.frame.height/2 cellProfile.profile.clipsToBounds = true cellProfile.name.text = self.name cellProfile.email.text = self.email cell = cellProfile case 3: let cellAccount = (menuTableView.dequeueReusableCell(withIdentifier:"accountCell", for: indexPath)as? MenuAccountTableViewCell)! cellAccount.title.text = accountNames[indexPath.row] cellAccount.icon.image = fieldImages[indexPath.row] cell = cellAccount case 5: let cellLanguage = (menuTableView.dequeueReusableCell(withIdentifier:"languageCell", for: indexPath)as? MenuLanguageTableViewCell)! cellLanguage.languageLabel.text = languageNames[indexPath.row] cell = cellLanguage default: print("Something else") } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { switch indexPath.section { case 5: let currentCell = tableView.cellForRow(at: indexPath) as? MenuLanguageTableViewCell language = (currentCell?.languageLabel.text)! selectedIndex = -1 isSecondSectionHidden = true menuTableView.reloadData() default: print("Something else") } } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if indexPath.section == 0 { return 180 } else if indexPath.section == 3||indexPath.section == 5 { return 40 } return 0 } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { if section == 0 { return 0 } return 50 } func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let headerView = UIView(frame: CGRect(x: 0, y: 0, width: menuTableView.frame.size.width, height: 40)) let headerImage = UIImageView() headerImage.frame = CGRect(x: 15, y: 15, width: 12, height: 12) let headerLbl = UILabel() headerLbl.frame = CGRect(x: headerImage.frame.origin.x + headerImage.frame.size.width + 20, y: 10, width:menuTableView.frame.size.width - 40, height: 20) headerLbl.font = UIFont().robotoLight(withFontSize: 9) headerLbl.textColor = CustomColor.menuGrey.color let arrowImage = UIImageView() arrowImage.isHidden = true switch section { case 1: headerImage.image = UIImage(named: "home_icon") headerLbl.text = "Home" case 2: headerImage.image = UIImage(named: "my_Id_icon") headerLbl.text = "My ID" case 3: headerImage.image = UIImage(named: "my_interest_icon") headerLbl.text = "My Account" arrowImage.isHidden = false if isFirstSectionHidden { arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 3, height: 5) arrowImage.image = UIImage(named: "side_arrow") } else { arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 5, height: 3) arrowImage.image = UIImage(named: "down_arrow") } case 4: headerImage.image = UIImage(named: "my_profile_icon") headerLbl.text = "My Profile" case 5: headerImage.image = UIImage(named: "language_icon") headerLbl.text = language arrowImage.isHidden = false if isSecondSectionHidden { arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 3, height: 5) arrowImage.image = UIImage(named: "side_arrow") } else { arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 5, height: 3) arrowImage.image = UIImage(named: "down_arrow") } case 6: headerImage.image = UIImage(named: "notification_icon") headerLbl.text = "Notifications" case 7: headerImage.image = UIImage(named: "about_us_icon") headerLbl.text = "About Us" case 8: headerImage.image = UIImage(named: "faq_icon") headerLbl.text = "FAQ" case 9: headerImage.image = UIImage(named: "contact_us_icon") headerLbl.text = "Contact Us" case 10: headerImage.image = UIImage(named: "logout_icon") headerLbl.text = "Logout" default: print("Something else") } let headerClick = UIButton(type: .custom) headerClick.addTarget(self, action: #selector(self.headerAction), for: .touchUpInside) headerClick.frame = CGRect(x: 0, y: 0, width: menuTableView.frame.size.width, height: 40) headerClick.tag = section headerClick.backgroundColor = UIColor.clear headerView.addSubview(arrowImage) headerView.addSubview(headerLbl) headerView.addSubview(headerImage) headerView.addSubview(headerClick) return headerView } func headerAction(_ sender: UIButton) { if sender.tag == 3 { if isFirstSectionHidden { selectedIndex = Int(sender.tag) isFirstSectionHidden = false isSecondSectionHidden = true } else { selectedIndex = -1 isFirstSectionHidden = true } }else if sender.tag == 5 { if isSecondSectionHidden { selectedIndex = Int(sender.tag) isSecondSectionHidden = false isFirstSectionHidden = true } else { selectedIndex = -1 isSecondSectionHidden = true } } else { selectedIndex = -1 isSecondSectionHidden = true isFirstSectionHidden = true } menuTableView.reloadData() } } 

任何想法如何以编程方式将此视图控制器作为我的侧视图控制器。 请注意,我试图避开第三方课程。

https://i.stack.imgur.com/eDERN.gif

你可以做的很简单

现在

1.在Base View Controller中添加容器视图。 通过segue将侧视图控制器添加到容器视图

2.使容器视图宽度为275或根据要求。

3.向容器视图尾部添加约束(假设侧面菜单右侧视图),顶部,底部和恒定宽度。

4.现在在视图中创建尾随约束的出口,并将其常量值-275切换为隐藏,并将0显示。

PS我有示例项目也https://drive.google.com/open?id=0ByCC2aGldkpUVU0xUkd5bTRCNCNQ