Left Side Menu opens when Right Side Menu is Clicked in Swift - swift

I'm using ENSideMenu Library for creating the menus in my navigation bar in Swift. I already created the left side menu of the navigation bar, but then when I created the right side. What happen is, when I click the right side button that contains the action for showing the right menu... the left side menu is shown instead. Here's my current implementation.
RightSideNavigationController
override func viewDidLoad() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let menu = storyboard.instantiateViewController(withIdentifier: "RightMenuTableViewController") as! RightMenuTableViewController
sideMenu = ENSideMenu(sourceView: self.view, menuViewController: menu, menuPosition: ENSideMenuPosition.right)
sideMenu?.menuWidth = 200
view.bringSubview(toFront: navigationBar)
}
RightMenuTableViewController
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var destView: UIViewController!
if indexPath.row == 0 {
destView = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
} else {
destView = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
}
sideMenuController()?.setContentViewController(destView)
}
SideNavigationController
override func viewDidLoad() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let menu = storyboard.instantiateViewController(withIdentifier: "MenuTableViewController") as! MenuTableViewController
sideMenu = ENSideMenu(sourceView: self.view, menuViewController: menu, menuPosition: ENSideMenuPosition.left)
sideMenu?.menuWidth = 200
view.bringSubview(toFront: navigationBar)
}
MenuTableViewController
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var destinationViewController: UIViewController!
if indexPath.section == 0{
if indexPath.row == 0 {
destinationViewController = storyboard.instantiateViewController(withIdentifier: "TopViewController") as! TopViewController
} else if indexPath.row == 1 {
destinationViewController = storyboard.instantiateViewController(withIdentifier: "MemberListViewController") as! MemberListViewController
}
}else {
if indexPath.row == 0 {
destinationViewController = storyboard.instantiateViewController(withIdentifier: "MemberRegisterViewController") as! MemberRegisterViewController
} else if indexPath.row == 3 {
destinationViewController = storyboard.instantiateViewController(withIdentifier: "UserRegistrationViewController") as! UserRegistrationViewController
}
}
sideMenuController()?.setContentViewController(destinationViewController)
}

The ENSideMenu Library currently doesn't support 2 menus which uses the library in the same page. This is according to the issues posted in ENSideMenu Library GitHub

Related

Navigate to ViewController from #IBDesignable UIView didSelectRowAt UITableView

I have created a #IBDesignable View file and implemented tableview in it. Data is coming and tableView in working but only I am facing issue at the time of select cell which has to open to other ViewController. Because its a #IBDesignable view file, not a viewController.swift
How to navigate to viewController from #IBDesignable UIView tableview cell select with passing values?
Error: has no member 'navigationController' if I use self.
Code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let actionType = AppData?.items?[indexPath.row].actionType
switch actionType {
case 5:
print(actionType ?? 0)
let urlLink = AppData?.items?[indexPath.row].actionUrl
let titleText = AppData?.items?[indexPath.row].textValue
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
vc.url = urlLink ?? ""
vc.titleText = titleText ?? ""
self.navigationController.pushViewController(vc, animated: true)
default:
print(actionType ?? 0)
}
}
You can access the parent view controller using this extension:
extension UIView {
var viewController: UIViewController? {
var responder: UIResponder? = self
while responder != nil {
if let responder = responder as? UIViewController {
return responder
}
responder = responder?.next
}
return nil
}
}
You can use it like this in your code:
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
vc.url = urlLink ?? ""
vc.titleText = titleText ?? ""
self.viewcontroller?.navigationController?.pushViewController(vc, animated: true)
Note: Although you can get the parent controller of UIView, it is not
recommended as the UIView should not be aware of the controller. I
suggest using Delegates.
Your UITableView is a UIView so it's not a UIViewController and has not UINavigationController.
You should create a delegate in your UITableView that will be implemented by your UIViewController.
Something like that :
protocol MyTableViewDelegate: class {
func didSelectRow(url: String, titleText: String)
}
Add a delegate variable in your table view like :
weak var delegate: MyTableViewDelegate?
and call your delegate like this :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let actionType = AppData?.items?[indexPath.row].actionType
switch actionType {
case 5:
print(actionType ?? 0)
let urlLink = AppData?.items?[indexPath.row].actionUrl
let titleText = AppData?.items?[indexPath.row].textValue
self.delegate.didSelectRow(url: url, titleText: titleText)
default:
print(actionType ?? 0)
}
}
In your view controller :
you should add your table view custom class into your ViewController,
then add delegate : yourTableView.delegate = self
implement delegate :
extension MyViewController: MyTableViewDelegate {
func didSelectRow(url: String, titleText: String) {
let vc = storyboard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
vc.url = urlLink
vc.titleText = titleText
self.navigationController.pushViewController(vc, animated: true)
}
}

How to navigate from a custom collection view to a TabbarController in swift 4?

I have tried this but didn't work for me:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.layer.borderColor = UIColor.gray.cgColor
cell?.layer.borderWidth = 0.5
print("swift")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "Action") as! UIViewController
self.navigationController?.pushViewController(viewController, animated: true)
}
You are pushing to a UIViewController.
You might be pushing to a UIViewController inside UITabbarController. To navigate to UITabbarController you need to instantiate the UITabbarController and push to it.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "TabBar") as! UITabBarController
self.navigationController?.pushViewController(viewController, animated: true)
*//Get reference to your tab bar.*
let tabBar:UITabBarController = self.window?.rootViewController as! UITabBarController
let navInTab:UINavigationController = tabBar.viewControllers?[1] as! UINavigationController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationViewController = storyboard.instantiateViewControllerWithIdentifier("ControllersName") as? ControllersType
navInTab.pushViewController(destinationViewController!, animated: true)
*//To whichever index you want to navigate.*
tabBar.selectedIndex = 1
**Hope this helps.**
You should segue to the tab bar controller, not the UIViewController contained by it.
An easy way to do it is setting a segue using your storyboard and call performSegue when you want to initiate the transition.
First set the storyboard as follows:
Then you may call self.performSegue(withIdentifier: "logInSegue", sender: self)
(logInSegue is the name of my segue but obviously you should change it to your segue identifier you have set in your storyboard)

Swift: Can't push to view controller programatically

I'm trying to push to different viewcontroller programatically using this code:
let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! MenuController
self.navigationController?.pushViewController(loginVC, animated: true)
Here is my setup: I have swift file called: MenuController which contains this code I set the identifier name to: LoginViewController I set the class of both ViewControllers set to MenuController. But whenever I press the button to trigger the event it doesn't do anything.
Here is the rest of my code as requested:
import UIKit
class MenuController: UIViewController {
var thingy = 0
#IBAction func ThingyBttn(_ sender: UIButton) {
if(thingy == 1) {
print("ok")
}else{
print("good")
let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! MenuController
self.navigationController?.pushViewController(loginVC, animated: true)
}
}
#IBOutlet var myButton: UIButton!
#IBAction func Button(_ sender: UIButton) {
if let ButtonImage = myButton.image(for: .normal),
let Image = UIImage(named: "ButtonAppuyer.png"),
UIImagePNGRepresentation(ButtonImage) == UIImagePNGRepresentation(Image) {
thingy = 1
print("1")
} else {
thingy = 2
print("2")
}
}
}
I know that everything else with the code works fine because it's printing the message.
You need to insert the vc you do the push from inside a navigationController as this
self.navigationController?
is nil , or do it programmatically
Edit:
Replace this
let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! MenuController
self.navigationController?.pushViewController(loginVC, animated: true)
with
let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! MenuController
let nav = UINavigationController(rootViewController:self)
(UIApplication.shared.delegate as! AppDelegate).window!.rootViewController = nav
nav.pushViewController(loginVC, animated: true)
I think your view controllers are not in Navigation Stack thats why its not pushing to next view controller
let nextVC = self.storyboard?.instantiateViewController(withIdentifier: “nextvc”) as! nextvc
let navigation = UINavigationController(rootViewController:self)
UIAppliaction.window!.rootViewController = navigation
navigation.pushViewController(nextVC, animated: true)

Change destination viewController when editing is true or false

I have a viewControllerwith a tableViewwhich contains all clubs, the user added. The user can reorder the tableViewCellswith the moverowatfunction. If he selects a club, he comes to a tableViewwith all members from the club. Now I want to implement the ability, to get to another viewController where he can edit the content of the cell.
I have created this, but now it doesn't work:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableViewClub.isEditing == true{
self.navigationController?.pushViewController(EditClubViewController() as UIViewController, animated: true)}
if tableViewClub.isEditing == false{
self.navigationController?.pushViewController(MemberViewController() as UIViewController, animated: true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if !tableViewClub.isEditing {
guard let destination = segue.destination as? MemberViewController,
let selectedRow = self.tableViewClub.indexPathForSelectedRow?.row else {
return
}
destination.club = clubs[selectedRow]
}}
When tableView.isEditing, then a viewController with a black background is shown. When !tableView.isEditing, this error is shown:Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value. I think it is because I have no storyboard segues. But is it possible, to have two segues from the tableViewCell? Or how should I solve this problem?
Don't use Interface Builder's segue. Instantiate the destination view controller manually so you can control which one you are transitioning to:
Interface Builder
Select the EditClubViewController and give it a Storyboard ID. Do the same to MemberViewController.
In code
In the first view controller:
override func viewDidLoad() {
super.viewDidLoad()
// Turn this on so rows can be tapped during editing mode
tableView.allowsSelectionDuringEditing = true
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let destinationVC: UIViewController
switch tableView.isEditing {
case true:
// If your storyboard isn't named "Main.storyboard" then put the actual name here
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "editClubViewController") as! EditClubViewController
// do your setup....
destinationVC = vc
case false:
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "memberViewController") as! MemberViewController
// do your setup...
destinationVC = vc
}
self.navigationController?.pushViewController(destinationVC, animated: true)
}

Table View To Custom View Controller?

I Wanted to know if I have two cells in a tableview, and I want that if i click the first cell it seagues to specific view controller, and if I click the second cell it seagues to another view controller.
How can I do that?
You can do it this way in didSelectRowAtIndexPath method:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
switch indexPath.row {
case 0 :
println("First cell")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)
case 1 :
println("Second Cell")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)
default:
println("No cell selectd")
}
}
HERE is your sample project.
Call performSegue:withIdentifier: from the method didSelectRowAtIndexPath in your view controller. You can conditionally call segues with different identifiers in your code.