I implemented SWRevealController with storyboard and everything works great, but now I would like to program the app without storyboard.
Can someone help me with the implementation? I have a FrontViewController and a MenuViewController. Do I need an extra SWRevealViewController for this and if yes, what do I have to code?
I know there is some information on SWRevealController but it is in Objective-C and I have some problems to write this in Swift 2.0.
You can do it as follow.
Create one function createSlidingMenu in appDelegate.
func createSlidingMenu(){
let frontViewController = //create instance of frontVC
let rearViewController = //create instance of rearVC(menuVC)
//create instance of swRevealVC based on front and rear VC
let swRevealVC = SWRevealViewController(rearViewController: rearViewController, frontViewController: frontViewController);
swRevealVC.toggleAnimationType = SWRevealToggleAnimationType.EaseOut;
swRevealVC.toggleAnimationDuration = 0.30;
//set swRevealVC as rootVC of windows
self.window?.rootViewController = swRevealVC!;
}
call createSlidingMenu in application:didFinishLaunchingWithOptions: and you are good to go.
This worked for me (in swift 3.1)
In the StoryBoard create MasterViewController, HomeViewController (embedded in UINavigationController) with storyboardId "HomeViewController", and MenuViewController (embedded in UINavigationController) with storyboardId "MenuViewController".
Create MasterViewController class and associate to UIViewController (MasterViewController) in Storyboard and implements SWRevealViewControllerDelegate protocol (see code)
import UIKit
class MasterViewController: UIViewController, SWRevealViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let frontNavigationController:UINavigationController
let rearNavigationController:UINavigationController
let revealController = SWRevealViewController()
var mainRevealController = SWRevealViewController()
let menuTable = self.storyboard?.instantiateViewController(withIdentifier: "MenuViewController")as! MenuViewController
let homepage = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
frontNavigationController = UINavigationController(rootViewController: homepage)
rearNavigationController = UINavigationController(rootViewController: menuTable)
rearNavigationController.setNavigationBarHidden(true, animated: false)
revealController.frontViewController = frontNavigationController
revealController.rearViewController = rearNavigationController
revealController.delegate = self
mainRevealController = revealController
UIApplication.shared.delegate!.window?.rootViewController = mainRevealController
}
}
As alternative you could omit MasterViewController and:
implement SWRevealViewControllerDelegate in AppDelegate and
copy the code of viewDidLoad body wrote above in application:didFinishLaunchingWithOptions:
In addition to Hitendra, I modify the following code so I can put navigation in Home
AppDelegate.swift
func toHome() {
let frontViewController = HomeController()//create instance of frontVC
let rearViewController = MenuController() //create instance of rearVC(menuVC)
let swRevealVC = SWRevealViewController(rearViewController: rearViewController, frontViewController: frontViewController);
swRevealVC?.toggleAnimationType = SWRevealToggleAnimationType.easeOut;
swRevealVC?.toggleAnimationDuration = 0.30;
navigationController = UINavigationController(rootViewController: swRevealVC!)
self.window?.rootViewController = navigationController
}
LoginController.swift, when user click login button
#objc private func login() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.toHome()
return
}
HomeController.swift
override func viewDidLoad() {
super.viewDidLoad()
setupLayout() // layout programmatically, I didn't put code here
let menuButton = UIBarButtonItem(title: "Menu", style: .plain, target: self, action: #selector(HomeController.menu))
self.revealViewController().navigationItem.leftBarButtonItem = menuButton
}
#objc private func menu() {
revealViewController().revealToggle(self)
}
Related
I am failing to understand the fundamentals of what is needed to add my HomeViewController (UIViewController) as one of the tabs in my homeTabBarController (UITabBarController) using the setViewControllers method.
I have tried initializing this and simply adding it as a param in the method. There seems to be a difference between a view controller created via storyboard and one created programmatically because when I tried adding a viewcontroller:UIViewController programmatically to the setViewControllers method, it worked fine.
My code below compiles however I get a runtime exception Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ff7b8491598) at the line when homeTabBarController.setViewControllers is called
`
func loadTabBar() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let homeViewController = storyboard.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
homeViewController!.title = "Home"
homeTabBarController.setViewControllers([homeViewController!], animated: false)
homeTabBarController.modalPresentationStyle = .fullScreen
present(homeTabBarController, animated: true)
}
`
//MARK: - Create the instances of ViewControllers
let grayViewController = HomeViewController()
let blueViewController = FirstViewController()
let brownViewController = SecondViewController()
override func viewDidLoad() {
super.viewDidLoad()
//set title of the viewcontrollers
grayViewController.title = "home"
blueViewController.title = "first"
brownViewController.title = "second"
//Assigne the viewcontrollers to the TabBarViewController
self.setViewControllers([ grayViewController, blueViewController, brownViewController], animated: false)
//set system images to each tabBars
guard let items = self.tabBar.items else {
return
}
let images = ["house.fill", "star.fill", "bell.fill"]
for i in 0...2 {
items[i].image = UIImage(systemName: images[i])
}
self.tabBar.tintColor = .black
}
// You can download the project from the below github link
https://github.com/ahmetbostanciklioglu/AddingTabBarControllerProgrammatically.git
I have implemented a tabBar programmatically:
class ViewController: UIViewController {
let tabBarCnt = UITabBarController()
override func viewDidLoad() {
super.viewDidLoad()
tabBarCnt.tabBar.tintColor = UIColor.black
createTabBarController()
}
func createTabBarController() {
let firstVc = UIViewController()
let downloadViewController = DownloadsViewController()
downloadViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .downloads, tag: 0)
let bookmarkViewController = BookmarksViewController()
bookmarkViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .bookmarks, tag: 1)
let favoritesViewControllers = FavoritesViewController()
favoritesViewControllers.tabBarItem = UITabBarItem(tabBarSystemItem: .favorites, tag: 2)
// Adding navigationControllers
let controllerArray = [downloadViewController, bookmarkViewController, favoritesViewControllers]
// For somereason this made the word Home appear in first tab
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
}
}
DownloadViewController.swift
class DownloadsViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.green
self.title = "Downloads"
}
}
This is the result:
MY QUESTION IS:
Do I have to implement all the layouts of the different viewControllers downloadViewController, bookmarkViewController, favoritesViewControllers programmatically?
Can't I use the storyboard and associate a viewController and do all the UI design and implementation there like this:
The problem here is that if I will implement all the layout programmatically, it won't be an obvious or a practical thing to do.
And assigning DownloadsViewController to that storyboard ViewController, doesn't make it get display it when I navigate to DownloadsTab in the UITabBar.
Yes, you can do that currently your creating view controller instance programmatically, instead of that you have to load/get viewController instance from storyBoard like this.
UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(identifier: "downloadsVC") as! DownloadsViewController
before calling this method set viewController StoryboardID
I want to add navigationController to just only for HomeViewController for example. I know how to do it from AppDelegate and like this below
let navBar = UINavigationController(rootViewController: homeViewController())
self.present(navBar, animated: true, completion: nil)
Is there another way that I can add navigationController inside viewDidLoad and viewWillAppear?
Edited:
My logic is when I pressed Login button which is the code below. Then it will present SWRevealViewController
#IBAction func loginPressed(_ sender: Any) {
let frontViewController = HomeViewController()
let rearViewController = TableViewController()
let swRevealVC = SWRevealViewController(rearViewController: rearViewController, frontViewController: frontViewController)
swRevealVC?.toggleAnimationType = SWRevealToggleAnimationType.easeOut
swRevealVC?.toggleAnimationDuration = 0.30
self.present(swRevealVC!, animated: true, completion: nil)
}
I just only want to set navigationController to HomeViewController
Replace
let frontViewController = HomeViewController()
with
let frontViewController = UINavigationController(rootViewController: HomeViewController())
and it will work.
Look below code hope it works for you...
This will be in App delegate
if UserDefaults.standard.bool(forKey: REMEMBER_ME) {
let menuVC = UINavigationController(rootViewController: SideMenuViewController())
let loginVC = UINavigationController(rootViewController: DashboardViewController())
let revealViewController = SWRevealViewController(rearViewController: menuVC, frontViewController: loginVC)
self.navigationController?.navigationBar.isHidden = true
window?.rootViewController = revealViewController
} else {
window?.rootViewController = LoginViewController()
}
This will be in your login action
if let window = UIApplication.shared.keyWindow {
let menuVC = UINavigationController(rootViewController: SideMenuViewController())
let loginVC = UINavigationController(rootViewController: DashboardViewController())
let revealViewController = SWRevealViewController(rearViewController: menuVC, frontViewController: loginVC)
self.navigationController?.navigationBar.isHidden = true
window.rootViewController = revealViewController
}
in my app i am using slider so i am using this library.
https://github.com/dekatotoro/SlideMenuControllerSwift
but while using this i am confused in use of navigation bar.
in my appdelegate i write down this code
window = UIWindow(frame: UIScreen.mainScreen().bounds)
storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller123 : MainViewController = (self.storyboard!.instantiateViewControllerWithIdentifier("MainViewController") as? MainViewController)!
let controllerright : drawerViewController = self.storyboard!.instantiateViewControllerWithIdentifier("drawerViewController") as! drawerViewController
let controllerleft : RightViewController = self.storyboard!.instantiateViewControllerWithIdentifier("RightViewController") as! RightViewController
let controller = SlideMenuController (mainViewController: controller123, leftMenuViewController: controllerleft, rightMenuViewController: controllerright)
navigation = UINavigationController(rootViewController: controller)
window?.rootViewController = navigation
window?.makeKeyAndVisible()
and in my mainviewcontroller i add drwer by this code
slideMenuController()?.addRightBarButtonWithImage(UIImage(named: "ic_menu_black_24dp")!)
because i want drawer on right side
and when i select one item from drawer i write this code
let controller123 : RightViewController = (self.storyboard!.instantiateViewControllerWithIdentifier("RightViewController") as? RightViewController)!
let controllerright : drawerViewController = self.storyboard!.instantiateViewControllerWithIdentifier("drawerViewController") as! drawerViewController
let controllerleft : RightViewController = self.storyboard!.instantiateViewControllerWithIdentifier("RightViewController") as! RightViewController
let controller = SlideMenuController (mainViewController: controller123, leftMenuViewController: controllerleft, rightMenuViewController: controllerright)
navigationController?.pushViewController(controller, animated: false)
but now issue is that i can not set navigation bar title or even i can not hide back button so how can i solve that?
Try something like this. Add this line in your viewDidLoad() method of drawerViewController
self.navigationItem.hidesBackButton = true
self.navigationItem.title = "Your Title"
//If you want to create a custom title View then try this
self.navigationItem.titleView = yourview
Hope this will help you.
try this code "override func viewWillAppear(animated: Bool)" in current view controller :
navigationItem.hidesBackButton = true;
navigationItem.title = "Hello";
hope this code will help you.
Try this in viewDidLoad in each ViewController that navigates from Drawer
self.navigationItem.hidesBackButton = true
self.navigationItem.title = "Title"
I need your help.
I'm developing a app without Storyboard (using xib), in my project I have two views controllers.
In the main view (after a login) I need to put a button on top of the view to open a left side menu.
This is how I call the MainView on LoginViewController
#IBAction func logar(){
let vc = MainViewController(nibName: "MainViewController", bundle: nil)
self.navigationController!.pushViewController(vc, animated: true)
}
I imported SWRevealViewController, and this is my MainViewController:
import UIKit
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//hide BackButton
self.navigationItem.hidesBackButton = true
//image
var image = UIImage(named: "menuBtn")
image = image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
//lefBarButonItem
let newBackButton = UIBarButtonItem(image: image, style: .Plain, target: self, action: #selector(MainViewController.openMenu))
self.navigationItem.leftBarButtonItem = newBackButton;
}
func openMenu(){
let frontViewController = LeftMenuTableViewController()
let rearViewController = MainViewController()
//create instance of swRevealVC based on front and rear VC
let swRevealVC = SWRevealViewController(rearViewController: rearViewController, frontViewController: frontViewController);
swRevealVC.toggleAnimationType = SWRevealToggleAnimationType.EaseOut;
swRevealVC.toggleAnimationDuration = 0.30;
//set swRevealVC as rootVC of windows
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window!.rootViewController = swRevealVC
}
}
When I press the button the LeftMenu occupy all the view, not like a partial view.
Any help would be appreciated. Thank you!