Add navigationController to specif viewController programmatically without storyboard swift - ios

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
}

Related

Navigation Bar disappears when going back to Home VC from a Details VC from Push Notification

If I click on the push notification, it takes me to the details page but when I click on the programatically created back button, it takes me back to HomeVC but with the top nav bar gone. Here is my app delegate function where I present the details VC :
private func gotoDetailsVC(value : String)
{
guard let window = UIApplication.shared.connectedScenes.filter({$0.activationState == .foregroundActive
|| $0.activationState == .background || $0.activationState == .foregroundInactive}).compactMap({$0 as? UIWindowScene}).first?.windows.filter({$0.isKeyWindow}).first
else { return }
let storyboard = UIStoryboard(name: "Home", bundle: nil)
let detailsVC = storyboard.instantiateViewController(identifier: "viewDeviceDataController") as viewDeviceDataController
detailsVC.deviceID = value
detailsVC.didComeFromPN = true
let navController = UINavigationController(rootViewController: detailsVC)
navController.modalPresentationStyle = .popover
// you can assign your vc directly or push it in navigation stack as follows:
window.rootViewController = navController
window.makeKeyAndVisible()
}
And here is my back button on the DetailsVC :
#objc func backAction() {
let storyboard = UIStoryboard.init(name: "Home", bundle: nil)
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
homeVC.modalPresentationStyle = .automatic
present(homeVC, animated: true, completion: nil)
}
How can I resolve this issue? Please help.
Resolved by navigating to root Navigation Controller.
#objc func backAction() {
let storyboard = UIStoryboard.init(name: "Home", bundle: nil)
let homeVC = storyboard.instantiateViewController(withIdentifier: "navControllerHome") as! UINavigationController
homeVC.modalPresentationStyle = .fullScreen
present(homeVC, animated: true, completion: nil)
}
Usually back action would just return to a previous state, but here it seems you are recreating the view.
I would not make private func gotoDetailsVC(value : String) replace rootViewController and instead make it be presented by current navigationController then on your back action you would not create a new home but dismiss your detail screen.

Present VC programmatically

How to present UIViewController() inside of UINavigationController ? My controller presenting not fullscreen. I want my app to look like this enter image description here, but it is end up like this enter image description here
I making app without Storyboard(Programmatically)
let customVC = UIViewController()
customVC.view.backgroundColor = .green
customVC.modalPresentationStyle = .fullScreen
let navVC = UINavigationController(rootViewController: customVC)
self.present(navVC, animated: true, completion: nil)
let customVC = DestinationController()
let navVC = UINavigationController(rootViewController: customVC)
// this line overFullScreen
navVC.modalPresentationStyle = .overFullScreen
// for more style
navVC.modalTransitionStyle = .crossDissolve
self.present(navVC, animated: true, completion: nil)
your class where you want to go or present
class DestinationController:UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
}
}

Presenting NavigationController with TabBarViewController can not select index programmatically

I am trying to present NavigationController and select second tab in the completion block. My code is:
let chatViewController = UITabBarController()
let navigationController = UINavigationController(rootViewController: chatViewController)
present(navigationController, animated: true, completion: {
self.visibleViewController = navigationController
self.visibleViewController?.tabBarController?.selectedIndex = 1
})
Second attempt:
let chatViewController = UITabBarController()
let navigationController = UINavigationController(rootViewController: chatViewController)
navigationController.tabBarController?.selectedIndex = 1
present(navigationController, animated: true, completion: {
self.visibleViewController = navigationController
})
In both cases tabBarController is nil. How can I switch to different tab?
You are trying to access UITabBarController of UINavigationController, but you need to access the very first controller from UINavigationController and from there you need to make your UITabBar selected like this way:
func showTabBarControllerr() {
let chatViewController = UITabBarController()
//Note: Make sure you have already added the Controllers in Tabbarcontroller
chatViewController.viewControllers = [DemoOne(), DemoTwo()]
let navigationController = UINavigationController(rootViewController: chatViewController)
present(navigationController, animated: true, completion: {
if let tabBarController = navigationController.viewControllers.first as? UITabBarController {
tabBarController.selectedIndex = 1
}
})
}
Let me know this helps or not!
Instead of calling
present(navigationController, animated: true, completion: { })
in viewDidLoad, try to call it in viewWillAppear or viewDidAppear
Try this (Swift 5):
Set an identifier to your UITabBarController in the Storyboard, something like MainTabBar
Into a function or IBAction, use this code:
let tbc = storyboard?.instantiateViewController(withIdentifier: "MainTabBar") as! UITabBarController
tbc.selectedIndex = 1 // This is the index of your controller
present(tbc, animated: false, completion: nil)

Back to root view controller in swift

Is there any way to dismiss all the view controllers ( in which some controllers are pushed through navigation) and go back to the root view controller. I saw lots of examples but they didn't work in my application. I am using swift 4
This is code in appdelegate
func setNavigationToRootViews(){
storyBoard = UIStoryboard(name: "Main", bundle: nil)
nav = storyBoard?.instantiateViewController(withIdentifier: "mainNavigation") as! UINavigationController?
let accessToken: String? = KeychainWrapper.standard.string(forKey: "token")
print(accessToken as Any)
if accessToken != nil {
let homeVc = storyBoard?.instantiateViewController(withIdentifier: "Home-VC") as! HomeViewController
nav?.pushViewController(homeVc, animated: false)
}else{
let welcomVc = storyBoard?.instantiateViewController(withIdentifier: "login-VC") as! LoginViewController
nav?.pushViewController(welcomVc, animated: false)
}
let leftMenuVC = storyBoard?.instantiateViewController(withIdentifier: "menu-VC") as! MenuViewController
container = MFSideMenuContainerViewController.container(withCenter: nav, leftMenuViewController: leftMenuVC, rightMenuViewController: nil)
container?.panMode = MFSideMenuPanModeNone
window?.rootViewController = container
window?.makeKeyAndVisible()
}
and this in my last View controller
#IBAction func okayBtnTapped(_ sender: Any) {
_ = self.navigationController?.popToRootViewController(animated:
true)
dismiss(animated: true, completion: nil)
}
Try this one:
self.navigationController?.popToRootViewController(animated: true)
You can just set a new RootController like this:
let storyboard = UIStoryboard(name: "sName", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "<YOUR ROOT CONTROLLER>")
self.window?.rootViewController = viewController
If you don't have a window at self.window you need to instanciate one based on your AppDelegate.
If you're within a NavigationController you can also use the answer of #Anshul Bhatheja
Check you navigation controller, and view controllers inside that navigation controller. It seems debugging issue.
this method popToRootViewController(animated:) is the method should work
If you are working with simple push navigation controller and you want to go back to root view controller then you simply have to write
_ = self.navigationController?.popToRootViewController(animated: true)
extension UINavigationController {
func popToViewController(ofClass: AnyClass, animated: Bool = true) {
if let vc = viewControllers.filter({$0.isKind(of: ofClass)}).last {
popToViewController(vc, animated: animated)
}
}
func popViewControllers(viewsToPop: Int, animated: Bool = true) {
if viewControllers.count > viewsToPop {
let vc = viewControllers[viewControllers.count - viewsToPop - 1]
popToViewController(vc, animated: animated)
}
}
}
pop to SomeViewController class
navigationController?.popToViewController(ofClass: SomeViewController.self)
pop 2 view controllers
navigationController?.popViewControllers(viewsToPop: 2)

Programmatically add tab to tab bar

I have an app with a UITabBarController as my initial view controller.
Currently I'm doing everything in Storyboard but I want to programmatically add a tab to the tab bar based on a user being logged in or not.
I made a TestViewController to test this out. Right now I have two tabs (pictured below). I want to have a third tab positioned on the right programmatically. I put this code in my AppDelegate's didFinishLaunching method. Based on print statements the view controller is being added to the tab bar but it is not appearing in the tab bar then the app loads.
Any suggestions?
func addTabTEST() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabController = storyboard.instantiateViewControllerWithIdentifier("RootTabController") as! UITabBarController
let TestVC = storyboard.instantiateViewControllerWithIdentifier("TestViewController") as! TestViewController
let icon = UITabBarItem(title: "test", image: nil, selectedImage: nil)
TestVC.tabBarItem = icon
print("TAB CONTROLLERS 1: \(tabController.viewControllers)")
tabController.addChildViewController(TestVC)
tabController.viewControllers![2] = TestVC
print("TAB CONTROLLERS 2: \(tabController.viewControllers)")
}
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let nav1 = UINavigationController()
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let first: ViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
nav1.viewControllers = [first]
nav1.setNavigationBarHidden(true, animated: true)
nav1.title = "first"
let nav2 = UINavigationController()
let second: SecondViewController = mainStoryboard.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
nav2.viewControllers = [second]
nav2.setNavigationBarHidden(true, animated: true)
nav2.title = "second"
let nav3 = UINavigationController()
let third: ThirdViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ThirdViewController") as! ThirdViewController
nav3.viewControllers = [third]
nav3.setNavigationBarHidden(true, animated: true)
nav3.title = "third"
let tabController = UITabBarController()
tabController.viewControllers = [nav1,nav2,nav3]
tabController.selectedIndex = 0
self.window!.rootViewController = tabController
self.window?.makeKeyAndVisible()
this is for swift 4
self.window = UIWindow(frame: UIScreen.main.bounds)
let nav1 = UINavigationController()
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let first = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
nav1.viewControllers = [first]
nav1.setNavigationBarHidden(true, animated: true)
nav1.title = "first"
let nav2 = UINavigationController()
let second: HomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController2") as! HomeViewController2
nav2.viewControllers = [second]
nav2.setNavigationBarHidden(true, animated: true)
nav2.title = "second"
let nav3 = UINavigationController()
let third = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController3") as! HomeViewController3
nav3.viewControllers = [third]
nav3.setNavigationBarHidden(true, animated: true)
nav3.title = "third"
let tabController = UITabBarController()
tabController.viewControllers = [nav1,nav2,nav3]
tabController.selectedIndex = 0
self.window!.rootViewController = tabController
self.window?.makeKeyAndVisible()
if you do not want to use UIStoryboard and if you have three view controllers named oneVC, twoVC, and threeVC you can use (works on Swift 5.3 with iOS 14.2)
let window = UIWindow(frame: UIScreen.main.bounds)
window.backgroundColor = .systemBackground
self.window = window
// Put image path if you want to have an image on your TabBar for this view controller
self.oneVC?.tabBarItem = UITabBarItem(title: "One", image: nil, selectedImage: nil)
self.twoVC?.tabBarItem = UITabBarItem(title: "Two", image: nil, selectedImage: nil)
self.threeVC?.tabBarItem = UITabBarItem(title: "Three", image: nil, selectedImage: nil)
let tabController = UITabBarController()
tabController.viewControllers = [oneVC, twoVC, threeVC]
tabController.selectedIndex = 0
self.window!.rootViewController = tabController
self.window?.makeKeyAndVisible()

Resources