Search code examples
iosswiftuinavigationcontrolleruitabbarcontrollerxcode10

How can I pass data loaded when my application finished launching thru my UITabBar to a UITableView?


I am a new iOS programmer and I am trying to make an application that involves the following flow:

-> UITabBar -> UINavController -> UITableViewController.

Initially the program was working when I have the following flow:

-> UINavController -> UITableViewController

But when I added the UITabBar (with the Embed In method)the I had two issues:

1) Casting the initial view from UITableView to UITabBarView 2) The data which have been restored from Archives of the phone are not loading in the TableView.

I managed to fix the casting issue with the UIStoryboard IDs, but I am not sure if this way I created the second problem of not passing data to the UITableView correctly.

The Casting problem has taking place at the appDelegate code. Here is the original code I had before incorporating the UITabBarView:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

let navController = window!.rootViewController as! UINavigationController

let SLBprojectController = navController.topViewController as! GR8TableView

SLBprojectController.SLBprojectDB = thisSLBprojectDB

return true
}

The problem with the above code was that it told me that it could not cast a TableViewController (GR8TableView) into a UITabBarView. I have managed to fix this by searching in the StackOverflow forums by making the following:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

let tabBarIntial : UITabBarController = mainStoryboardIpad.instantiateViewController(withIdentifier: "TabBar") as! UITabBarController

let navigationController:UINavigationController = mainStoryboardIpad.instantiateViewController(withIdentifier: "navController") as! UINavigationController

let navigationController1:UIViewController = mainStoryboardIpad.instantiateViewController(withIdentifier: "ViewController1")

let SLBprojectController = navigationController.topViewController as! GR8TableView

SLBprojectController.SLBprojectDB = thisSLBprojectDB

tabBarIntial.viewControllers = [navigationController, navigationController1]

tabBarIntial.selectedIndex = 0

return true

}

But after I fixed the "casting" issue then I am getting problems loading the data in the TableView. Not sure if this problem is related to the way I fixed the casting issue.

Any assistance would be much much appreciated!


Solution

  • The simplest answer would be to go back to logic similar to what worked for you, but with a slightly more complex relationship. For example, I created an app with a tab bar controller, a navigation controller in the first tab, and a FirstViewController embedded in the navigation controller.

    Since I don't have a database, I gave the FirstViewController a single instance variable called running.

    The following code finds the controller and sets the variable:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if let tabController = window!.rootViewController as? UITabBarController {
            if let navController = tabController.viewControllers![0] as? UINavigationController {
                if let firstController = navController.topViewController as? FirstViewController {
                    firstController.running = true
                } else {
                    print("Unexpected controller in navigation hierarchy: \(String(describing: navController.topViewController))")
                }
            } else {
                print("Unexpected contained controller: \(String(describing: tabController.viewControllers![0]))")
            }
        } else {
            print("Unexpected root controller: \(String(describing: window!.rootViewController))")
        }
        return true
    }
    

    Note that I'm not creating any new controllers. That's all done by default storyboard loading.

    I believe you should be able to adapt this to your own variable and class names.