UISplitview: access UITabBarController from appDelegate - swift

I need to access the UITabBarController, and the second of its subviews from the appDelegate.
This is what I have tried in applicationDidEnterBackground:
let splitViewController = self.window!.rootViewController as! UISplitViewController
let leftNavController = splitViewController.viewControllers.first as! UINavigationController
let tabController = leftNavController.tabBarController! as UITabBarController
let controllers : Array = tabController.viewControllers!
print("viewcontrollers \(controllers)")
The app crashes, complaining that tabController is nil. If i remove the UINavigation controller from storyboard, the UITabBarController is accessed easily with:
let tabController = splitViewController.viewControllers.first as! UITabBarController
What is the correct way to access the childcontrollers of the UITabBarController, where a UISplitView is the root?

Finally I found a solution. I had to use "childViewControllers" of the navigation controller like this:
let splitViewController = self.window!.rootViewController as! UISplitViewController
let leftNavController = splitViewController.viewControllers.first as! UINavigationController
let tabController = leftNavController.childViewControllers.first as! UITabBarController
let viewControllers : Array = tabController.viewControllers!
print("viewControllers \(viewControllers)")
Now I can easily access any of the viewControllers and run their methods from appDelegate :-)

Rather than embedding your tab bar controller in a navigation controller, you should embed the child view controllers in their own navigation controllers, like this:
Split View -> Tab Bar -> Navigation Controller #1 -> View Controller
-> Navigation Controller #2 -> View Controller
This is the correct way to use a tab bar in conjunction with a navigation controller.

Related

Swift How can I add Navigation Controller after creating Views

I created View Controllers and I want to add Navigation Controller now. I tried embed-in Navigation Controller to My DetailViewContoller(colorful View Controller) but I got an error. main.storyboard, error. How can I add Navigation Controller ?
In order to set view controller as navigation controller, you can set it programmatically by calling this function in appdelegate or scenedelegate or any point.
func setNavigationController() {
var viewController: UIViewController
let storyboard = UIStoryboard(name: "myStoryboardName", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "myVCID")
let rootViewController = UINavigationController(rootViewController: viewController)
rootViewController.setNavigationBarHidden(true, animated: false)
self.view.window?.rootViewController = rootViewController
}
If you want to set navigation controller through storyboard, then you have to first add navigation controller and set is root view controller to the controller you want to make it navigation controller.

How to embed a view controller into a navigation view controller programmatically

I am trying to embed my view controller into a navigation view controller so i get the navigation bar and all the other stuff like back buttons. I want to do it programmatically.
It is done like this:
// example ViewController
let myVC = UIViewController()
// create the NavigationController with my VC as root
let navCon = UINavigationController(rootViewController: myVC)

how can I move a data array between tab bar viewControllers when I have navigationControllers involved

I have a tab bar controller and 3 viewControllers connected to it and when I move data between the viewControllers I use the following code, which works perfect:
let secondTab = tabBarController?.viewControllers![1] as! ImageViewController
secondTab.imageArray = images
Now I added navigation to the second viewController with EDITOR->Embed In....so, there is now a navigationController between my ImageViewController and the tabBarController. How can I still get the data to the ImageViewController?
You can try
if let nav = tabBarController?.viewControllers![1] as? UINavigationController {
if let let secondTab = nav.topViewController as? ImageViewController
secondTab.imageArray = images
}
}

Tab bar disappeared when back to initial view controller

i have 2 view controllers then tab bar controller connected to 3 navigation controller , each navigation connected to multiple views .
The point that from one of these views that is connected to one of navigation controllers , i want to back again to the start screen , it good by this 2 lines :
let loginViewController = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController")
UIApplication.shared.keyWindow?.rootViewController = loginViewController
but after i do this and want to navigate again to the tab bar its disappeared from the view . I used this to navigate to tab bar :
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let viewTabController = self.storyboard?.instantiateViewController(withIdentifier :"MainTabBarController") as! MainTabBarController
viewTabController.selectedIndex = 1
appDelegate.window?.rootViewController = viewTabController
Thanks in advance.
When you use instantiateViewController you are making new instances of view controllers in memory while there is no need in your case , you have created them before. so you can dissmis your tabBar and go back to first screen like this (initial viewcontroller must be embeded into a navigation controller) :
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let navigationController = appDelegate.window?.rootViewController as! UINavigationController
navigationController.dismiss(animated: true, completion: nil)
for bringing back tabBar you can either save its instance in your app delegate and present it or use a storyboard segue to present it modally
:)

navigationController is nil in swift

I have two storyboard (Main and SB2)
I have one view controller in storyboard in Main and one in SB2
I perform
let SB2 = UIStoryboard(name: "SB2", bundle:nil)
let vc : UIViewController = self.SB2.instantiateViewControllerWithIdentifier("VC2")
self.showViewController(vc, sender: self)
After the second viewcontroller loads and this command is run, it prints nil:
print(self.navigationController) // prints nil
In SB2 (second storyboard) I clicked on the viewcontroller (VC2) and then clicked on Editor > Embed In > Navigation Controller. This placed a navigation controller with the storyboard and the root view controller is VC2. I triple checked this. The first sign of it being connected was the gray navigation bar on top. The second being that there is segue connecting the navigation controller to VC2 and the last place I could have checked is in the navigation controller utilities.
I am thinking that maybe I shouldn't transition from VC1 to VC2 directly but rather VC1 to NavigationController however I don't know how to do this or if its even possible.
I don't know when sb2 prints nil when in face a navigation controller is connected to it. Any help is appreciated.
You need to push the view controller (VC2) on to the navigation controller.
let SB2 = UIStoryboard(name: "SB2", bundle:nil)v
let nvc = SB2.instantiateViewControllerWithIdentifier("NVC") as! UINavigationController
let vc : UIViewController = self.SB2.instantiateViewControllerWithIdentifier("VC2")
nvc.pushViewController(vc, animated: true)
Then in your view controller try calling
self.navigationController
In your storyboard,
select the initial ViewController. With this view controller selected, choose the menu item
Editor -> Embed In -> Navigation Controller