How to use a view controller as a side menu in Swi

2019-07-28 03:02发布

问题:

I am trying to implement the side menu in my application programatically. So I have designed a view controller with half of its view as table view. The design as well as coding is done, now i wish to use this view controller as a Side Menu controller. My SideMenu Storyboard is:

Now my code looks like this:

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

Any idea how to do this view controller as my side view controller programatically. Note, i am trying to avoid the third party classes at the best.

回答1:

Simple you can do is

Now

1. In Base View Controller add a container view. Add Side View Controller to container view via segue

2. Make Container view width 275 or as per requirement.

3. Add constraints to container view trailing (assuming side menu right side of view), top , bottom and constant width.

4. Now create outlet of trailing constraint in view and toggle its constant value -275 to hide and 0 to show.

P.S. I have sample project also https://drive.google.com/open?id=0ByCC2aGldkpUVU0xUkd5bTRCNzQ