Select Menu items
Twitter Slide Out Menu
In this new section, we'll go ahead and move away from building out any further UI. Instead, let's go ahead and handle the actions of selecting the menu items in our app. To get the correct behavior, we'll pass back an IndexPath object to our BaseSlidingController as we tap items in our menu. Finally we can swap our our main panel with our desired views by adding components into the our red view container. Enjoy.

Comments (11)
Alex de Koning
4 years ago
Hi Brian, Great lessons, well worth the money. I get stuck at the point where you access the BaseSlidingController by calling the rootviewcontroller, because in my case the rootviewcontroller is a custom MainNavigationController. How would I access the BaseSlidingController without it being the rootviewcontroller? Thank you in advance.
Brian Voong
4 years ago
Alex de Koning
4 years ago
Hi Brian, I'm assuming I should in that case completely disregard the BaseSlidingController and simply run all the code from there into my MainNavigationController? Any tips on how to do this? :)
Brian Voong
4 years ago
Alex de Koning
4 years ago
But with your solution I would be calling closeMenu() from my navigationcontroller, although it lives within BaseSlidingController. Excuse my ignorance.
Brian Voong
4 years ago
Alex de Koning
4 years ago
Ok so in other words: I want to build this slidermenu into my current app which holds a navigation controller that initially holds a logincontroller as its main viewcontroller. Once the user logs in, the mainnavigation controller's main controller will be changed to the BaseSlidingController as such: let rootViewController = UIApplication.shared.keyWindow?.rootViewController guard let mainNavigationController = rootViewController as? MainNavigationController else { return } mainNavigationController.viewControllers = [BaseSlidingController()] self.navigationController?.popToRootViewController(animated: true) .. Instead of the redview you are using, in my case is a view that holds a map and additional buttons that use the pop function from the main navigation controller to other viewcontrollers. I'm trying to combine profile related viewcontrollers from within the slidingmenu with the current mapview including some buttons. But like I said, I get stuck at the point where I need to access the BaseSlidingController's closeMenu() function because the MainNavigationController is the root. With your initial solution I get the error: "Value of type 'MainNavigationController' has no member 'closeMenu'" Hence I wondered as to why I would refer to the MainNavigationController to access the openMenu() function as it doesn't have this function because it lives in the BaseSlidingController. Is there a way to combine this slidermenu with the current structure I am using? The slidermenu works fine up until the point I need to access the closeMenu() function to allow for the menu item selection in the slidermenu. Or is this slidermenu's sole purpose to act as a main navigation and thus will not combine with a navigationcontroller?
Brian Voong
4 years ago
daniel123
4 years ago
I am curious why it is that sometimes when you want to create a new UI element, a label for example, you create and instance of UILabel and then manipulate the properties while other times you created a computed property that is of type UILabel and then manipulate the properties inside the computed property's closure.
Brian Voong
4 years ago
daniel123
4 years ago
I believe my second question is related to Alex de Koning's question below. Why did you have to do this to access closeMenu(): let slidingController = UIApplication.shared.keyWindow?.rootViewController as? BaseSlidingViewController while this didn't work for me: let baseSlidingVC = BaseSlidingViewController() baseSlidingVC.closeMenu() I get an unwrapped optional crash but I don't understand why your way works but not my way. Thank you in advance.
Alex de Koning
4 years ago
I tried the exact same thing, receiving the exact same error.
Brian Voong
4 years ago
Adam El-Kadi
4 years ago
Hey Brian, How would you present a collectionViewController view when a menuItem is pressed. The app keeps crashing. I am sure it is not the same as just presenting a ViewController because you also have to set up the collectionViewFlowLayout, my code to presenting it is as follows: let eventsVC = EventsCollectionViewController() redView.addSubview(eventsVC.view)
Adam El-Kadi
4 years ago
Thanks
Adam El-Kadi
4 years ago
Nevermind, I got it. For anyone that may need it: let flowLayout = UICollectionViewLayout() rightViewController = CustomCollectionViewController(collectionViewLayout: flowLayout)
吳登秝
4 years ago
To be precise, the access control of closeMenu() is Internal rather than Public. Reference: https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html *Default Access Levels* All entities in your code (with a few specific exceptions, as described later in this chapter) have a default access level of internal if you don’t specify an explicit access level yourself. As a result, in many cases you don’t need to specify an explicit access level in your code.
Michael
4 years ago
Hello Brian, I have a question. I don't know why you're using 'didSelectRowAt ' function at "extension MenuController " not just "class MenuController: UITableViewController" in.. What is the different between "extension " and "class". Thank you.
Brian Voong
4 years ago
jiarongkoh
4 years ago
Hi Brian, I'm not sure if you have tried laying out the list label using autoLayout but it seems that I cant get it to work correctly. The results turned out that the label span way beyond the width of the screen, ie the text "label" appears to be close to the trailing edge of the screen even with textAlightment set to center. class ListsController: UIViewController { let label: UILabel = { let l = UILabel() l.translatesAutoresizingMaskIntoConstraints = false l.textAlignment = .center l.font = UIFont.systemFont(ofSize: 30, weight: .heavy) l.backgroundColor = .blue return l }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(label) // label.frame = view.frame label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true label.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true label.heightAnchor.constraint(equalToConstant: 50).isActive = true label.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true } } Is there anything I'm not doing correctly?
jiarongkoh
4 years ago
Ok nevermind, actually the fix was in your next video, by moving closeMenu() up before the switch statement. But I do not understand why would that fix the issue? Is it because of the layoutIfNeeded? which the view redraws itself?
Ahmed Al Abdulaal
4 years ago
Hello Brian, What would be a better way of accessing didSelectMenuItem method? What if BaseSlidingController is not my rootViewController?
Ahmed Al Abdulaal
4 years ago
If anyone is interested I solved this with NotificationCenter In BaseViewController viewDidLoad I have NotificationCenter.default.addObserver(self, selector: #selector(openMenu), name: Notification.Name(rawValue: "openMenu"), object: nil) In my main vc navbutton I have NotificationCenter.default.post(name: Notification.Name(rawValue: "openMenu"), object: nil)
sbedx4
4 years ago
thank you I needed that
MehmetEmre
4 years ago
Hello everyone one more quick question. I am not using base sliding controller. My root controller is still HomeController. When I fetch this method in MenuController "let homeContorller = HomeController() homeContorller.closeSideMenu()" it doesn't work can you help me *? NOTE: func closeSideMenu() { isMenuOpened = false performAnimations(transform: .identity) }
MehmetEmre
4 years ago
Can anyone help me ? I can't solve this problem
Brian Voong
4 years ago
MehmetEmre
4 years ago
But my HomeController is a CollectionViewController and it has a lot of headaches about layout issues and also I am using storyboard. I just want call a func from another controller its looking so basic but I can't even do this. Sorry I am new about swift.
romer_96p@hotmail.com
3 years ago
I’m using the TabBarController from your other course.. so I can’t cast it the way you did on 5:11min of this video.. don’t really know of to pass over the indexPath. I tried: let slidingController = BaseSlidingController() slidingController.didSelectMenuItem(indexPath: indexPath) But still crashes :/
Brian Voong
3 years ago
romer_96p@hotmail.com
3 years ago
Correction, the indexPath goes through but the closeMenu() crashes for some reason
romer_96p@hotmail.com
3 years ago
I see what u mean.. not sure how to do that either
romer_96p@hotmail.com
3 years ago
I did it!!! YEEEEESSS lmao let tabBarController = UIApplication.shared.keyWindow?.rootViewController as? BaseTapBarController let slidingController = tabBarController?.viewControllers?[0] as? BaseSlidingController slidingController?.didSelectMenuItem(indexPath: indexPath) it only took me a few hours to figure it out lol... don't know if this is still the best practice...
Brian Voong
3 years ago
Dualzo
3 years ago
Hi Brain I don't understand how you can cast to BaseSlidingController? i'm using BaseTapBarController from the JSON APIs course and its not possible to cast it like you do on 5:11min. The problem is also that i don't see how i can create an BaseslidingController if i am using tabBarController as rootController? i Have tried to use: let tabBarController = UIApplication.shared.keyWindow?.rootViewController as? BaseTapBarController let slidingController = tabBarController?.viewControllers?[0] as? BaseSearchController slidingController?.didSelectMenuItem(indexPath: indexPath) its not responding when i'm using this method.
HELP & SUPPORT