Ryguyu
Ryguyu

Reputation: 173

How to Pass data between tabBarControllers

I am currently trying to pass data between two UINavigationControllers with a UITableViewController attached to each. I am navigating between these two controllers via a UITabBarController. I have been trying to use vacawama's solution on Changing VC issue in Swift. How to pass data between views in tab bar controller? I am using the following code.

import UIKit

class placeData: Equatable {
var description : String
var selected : Bool

init (description : String, selected : Bool) {
    self.description = description
    self.selected = selected
}

}

class PlacesTabBarController: UITabBarController {

var placeDataArray = [placeData]()

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.
}


}

This is in the tabBarController custom class. In the other two controllers I declare the array I want to be pass between the view controllers and use the method in the link to populate the UITableViewController

var placeDataArray = [placeData]()

override func viewWillAppear(animated: Bool) {
    placeDataArray = (self.tabBarController as PlacesTabBarController).placeDataArray
}

When the controllers load, however, the arrays are empty. In the example in the link, all the rest of the code is within the viewWillAppear function, where I need my array to be available to all of the corresponding tableView functions. I am not sure if I am just equating the arrays to zero on load. But my thought was that they would repopulate. Not sure what the correct way to go about this is. Any help would be great.

EDIT: My current structure is as follows:

 UITabBarController
  |              |
UINavigation  UINavigation
Controller     Controller
  |              |
UITableView      UITableView
Controller       Controller

The array is populated when the first tab loads. What I am trying to do is have the populated array in the second view controller, and if I edit it in the second view controller, I want the edits to stay in the first. So I want it to be passed by reference.

Upvotes: 0

Views: 259

Answers (2)

Wez
Wez

Reputation: 10712

I would subclass the UITabBarController and make it a delegate for the two UITableViewControllers.

CustomTabBarController

protocol CustomTabBarDelegate {
    var places:Array<placeData> { get set }
}

class CustomTabBarController: UITabBarController, CustomTabBarDelegate {
    var places = Array<placeData>()

    override func viewDidLoad() {

        places = [PlaceData(),PlaceData()]

        var table1 = CustomTableViewController()
        var table2 = CustomTableViewController()

        table1.delegate = self
        table2.delegate = self

        var navController1 = UINavigationController(rootViewController: table1)
        var navController2 = UINavigationController(rootViewController: table2)

        self.viewControllers = [navController1, navController2]

    }
}

Then your TableViewControllers simply access the delegates array like so.

CustomTableViewController

class CustomTableViewController: UITableViewController {
    var delegate:CustomTabBarDelegate!

    override func viewDidAppear() {
        self.tableView.reloadData()
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return delegate.places.count
    }

}

Any changes to the array will be visible in each table after you .reloadData() - I have set the CustomTableViewController in my example to reload data every time the view appears, so when you change tabs they should refresh to show the latest changes.


It's worth mentioning that in time it would probably be cleaner to have a separate class that manages your data instead of holding the array in the TabBarController.

Upvotes: 1

Peter Damiaan
Peter Damiaan

Reputation: 31

You can always use the app delegate.. Set a property there and call it from anywhere in your application.

let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var yourNeededData = appDel.yourPassingAroundDataProperty

Upvotes: 0

Related Questions