I am using ENSwiftSideMenu for displaying side menu.
The problem is I am not using navigation bar and instead using custom view. The navigation bar is hidden.
Now there is a method in the library which makes the navigation bar on top of side menu.
Like this : view.bringSubviewToFront(navBar)
Now I am using this method for my customView like this:
view.bringSubviewToFront`(customView)
But this does not work. I have the subclassed the NavigationController as suggested by the library but I am still not able to bring my customview header on top of side menu.
I added a method in the NavigationController class:
func bringHeaderToFront(headerView:UIView) -> Void {
view.bringSubviewToFront(headerView)
}
But this does not work.
Here is the custom NavigationController code:
class CustomNavigationController: ENSideMenuNavigationController {
override func viewDidLoad() {
super.viewDidLoad()
let sideMenuController:SideMenuController = SingletonClass.sharedInstance.getViewControllerFromStoryboard("SideMenuController") as! SideMenuController
sideMenu = ENSideMenu(sourceView: self.view, menuViewController: sideMenuController, menuPosition:.Left)
//sideMenu?.delegate = self //optional
sideMenu?.menuWidth = 220.0 // optional, default is 160
sideMenu?.bouncingEnabled = false
//sideMenu?.allowPanGesture = false
// make navigation bar showing over side menu
view.bringSubviewToFront(navigationBar)
}
func bringHeaderToFront(headerView:UIView) -> Void {
view.bringSubviewToFront(headerView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - ENSideMenu Delegate
func sideMenuWillOpen() {
print("sideMenuWillOpen")
}
func sideMenuWillClose() {
print("sideMenuWillClose")
}
func sideMenuDidClose() {
print("sideMenuDidClose")
}
func sideMenuDidOpen() {
print("sideMenuDidOpen")
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Now how to bring my custom header to front / on top of side menu?
Related
In my application I used SWRevealViewController in order to implement the side menu. There, for some reason I had to put a view which is embed in a navigation controller, before the reveal view controller.
This is my storyboard
Everything works fine other than one thing. when I drag from the left edge of the screen to the right side (pan gesture) on my home view, instead of side menu it navigates me to the previous view (in here case to the middle view which contains a button in the middle).
This is how it looks like when dragging
I want to avoid this and get the side menu when dragging like that. Can someone help me on this. Any help would be highly appreciated.
Edit:
This is the front_view and rear_view
Take a ViewController.swift file for the initial ViewController having button.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// 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.
}
*/
}
There is no issue in the swrevealviewcontroller implementation but the native behavior of navigation controller is causing this issue.
You need to remove the popGesture from the navigation controller in any view controllers that you don't want to be able to use the swipe gesture:
var gestureRecognizer: UIGestureRecognizer? {
guard let nc = navigationController else { return nil }
return nc.interactivePopGestureRecognizer
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let gr = gestureRecognizer {
gr.isEnabled = false
}
}
I want to launch segue from tab bar item. When user touches an item on the tab bar. I want to launch a segue.
To do this I writed this code:
class TabBarController: UITabBarController, UITabBarControllerDelegate {
#IBOutlet var tabs: UITabBar!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
if item.tag == 3 {
self.performSegueWithIdentifier("test123", sender: self)
}
}
}
Actually it works well except a problem. This is launching segue but also switching the tab. I don't want this. It should just launch start segue shouldn't switch the tab.
How can I prevent this problem?
Here's the minimal changes to get your code work
in your viewDidLoad() add
self.delegate = self
Then implement delegate method
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
let shouldSelectIndex = tabBarController.viewControllers?.indexOf(viewController)
if shouldSelectIndex == 2
{
self.performSegueWithIdentifier("test123", sender: self)
return false
}
return true
}
That should work.
However I think you have design issues.
Subclass as a delegate is strange. Better separate delegate.
Instead of tag/indecies use introspection or another delegation or something
I have problem with UITabBar. I need to make a custom action for Item (UITabBarItem). What do I need to add to make it working?
import UIKit
class ViewController: UIViewController {
#IBOutlet var TabBar: UITabBarItem!
#IBOutlet var Item: UITabBarItem!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationController?.navigationBarHidden
self.navigationItem.hidesBackButton = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tabBar(tabBar: UITabBar!, didSelectItem item: UITabBarItem!) {
var selectedTag = tabBar.selectedItem?.tag
println(selectedTag)
if selectedTag == 0
{
}
else
{
}
}
}
In each ViewController place this function:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//set inital view
}
Then put your code to execute in here and when the view appears it will execute.
Okay then, what I think you want then is not a UITabBar but instead a UIToolBar. From Apple:
"A tab bar is a control, usually appearing across the bottom of the screen in the context of a tab bar controller, for giving the user one-tap, modal access to a set of views in an app. Each button in a tab bar is called a tab bar item and is an instance of the UITabBarItem class. If you instead want to give the user a bar of buttons that each perform an action, use a UIToolbar object."
For the UIToolBar description see:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIToolbar_Class/index.html#//apple_ref/occ/cl/UIToolbar
import UIKit
class CollectionHolderViewController: MainPageContentViewController { //MainPageContentViewController inherits from UIViewController
var collectionViewController = UICollectionViewController()
override func viewDidLoad() {
super.viewDidLoad()
self.collectionViewController = self.storyboard!.instantiateViewControllerWithIdentifier("TrophyRoom") as UICollectionViewController
// Do any additional setup after loading the view.
self.addChildViewController(collectionViewController)
self.view.addSubview(collectionViewController.view) //I tried collectionViewController.collectionView with no success either
self.collectionViewController.didMoveToParentViewController(self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
This code worked for a UIPageViewController but not for this UICollectionViewController.
I just see a blank white (default) UIViewController which is expected if the UICollectionViewController's view was NOT set. There is no error shown in XCode 6.
Help?
Edit: The code DOES in fact work : ) Just a tip, set the collectionViewController.view to have a frame that fills the screen for consistency otherwise it will fit just below the status bar.
I wish for the menu to be hidden when the front view controller is tapped on while the menu is visible.
I need to know an elegant solution to this that doesn't get me to add a gesturerecognizer on all my viewcontrollers
SWRevealViewController provides you with a tap gesture controller which is ready to use. So you can simply add it to your front controller :
self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
Moreover, if you want to do it only once, you can create a controller which adds this gesture recognizer, and then inherit from this class. Example in Swift :
class YourFrontViewControllerParentClass : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let revealController = self.revealViewController() {
// add the tap gesture recognizer to the front view (RootViewController) so that the sidebar menu closes when the user taps the front view when the side menu is closed.
self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
}
}
}
class YourFrontViewControllerChildClass1 : YourFrontViewControllerParentClass {
override func viewDidLoad() {
super.viewDidLoad()
// specific stuff
}
}
class YourFrontViewControllerChildClass2 : YourFrontViewControllerParentClass {
override func viewDidLoad() {
super.viewDidLoad()
// specific stuff
}
}
class YourFrontViewControllerChildClass3: YourFrontViewControllerParentClass {
override func viewDidLoad() {
super.viewDidLoad()
// specific stuff
}
}