问题
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
来源:https://stackoverflow.com/questions/45724460/how-to-use-a-view-controller-as-a-side-menu-in-swift3