6

I want to pass information from a ViewController to a UITabBarController so that I can access certain information from the view controller in the 3rd tab of the UITabBarController.

However, the issue is my program keeps crashing when I try to do so. Here is my code so far:

I call the segue like so:

self.firstName = user.first_name
self.lastName = user.last_name
self.performSegueWithIdentifier("OffersView", sender: self)

And I override the prepareForSegue function so that I can pass information in this function like so:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if(segue.identifier == "OffersView"){
        let barViewControllers = segue.destinationViewController as UITabBarController
        let destinationViewController = barViewControllers.viewControllers![2] as ProfileController
        destinationViewController.firstName = self.firstName
        destinationViewController.lastName = self.lastName
    }
}

When I try to set the destinationViewController (on the second line in the code above), my code crashes. I'm not sure why as I've looked on numerous StackOverflow posts such as

Swift tab bar view prepareforsegue and Pass data from tableview to tab bar view controller in Swift. but have not have much success. Do I possibly need to create a UITabBarControllerDelegate class and pass information through that? Any tips would be appreciated. Thanks!

Community
  • 1
  • 1
user1871869
  • 3,317
  • 13
  • 56
  • 106
  • It crashes with what error message? – rdelmar Apr 11 '15 at 01:00
  • @rdelmar it doesn't seem to display any particular error message. – user1871869 Apr 11 '15 at 01:01
  • In a test app, your code worked fine for me after changing the two "as" words to "as!" in prepareForSegue. – rdelmar Apr 11 '15 at 01:09
  • Can you give me an example of how you did that? I added in an exclamation point in front of the "as" word but I got an error saying "Expected type after as" @rdelmar – user1871869 Apr 11 '15 at 01:14
  • It goes after the as, **as!**, not before. – rdelmar Apr 11 '15 at 01:23
  • @rdelmar ah yes sorry I wasn't clear. I did put it after the as but I get the error as I have said above. This is how my code looks: `let destinationViewController = barViewControllers.viewControllers![2] as! ProfileController` and the error is "Expected type after as" – user1871869 Apr 11 '15 at 01:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74980/discussion-between-rdelmar-and-user1871869). – rdelmar Apr 11 '15 at 01:27

3 Answers3

12

The problem, as discovered after a discussion, was that the tab bar controller's children were embedded in navigation controllers, so the code needed to be changed to this,

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    let barViewControllers = segue.destinationViewController as! UITabBarController 
    let nav = barViewControllers.viewControllers![2] as! UINavigationController 
    let destinationViewController = nav.topviewcontroller as ProfileController 
    destinationViewController.firstName = self.firstName
    destinationViewController.lastName = self.lastName 
}
Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
rdelmar
  • 103,982
  • 12
  • 207
  • 218
3

In swift 3, xcode 8 that code would be like

let barViewControllers = segue.destination as! UITabBarController
let nav = barViewControllers.viewControllers![0] as! UINavigationController
let destinationViewController = nav.viewControllers[0] as! YourViewController
        destinationViewController.varTest = _varValue
  • 1
    How do you find out which tab is chosen and set the variable for that particular tabView? – jl303 May 28 '17 at 03:59
  • In my case I needed to navigate to "YourViewController". My guess is in viewControllers array is stored all controllers (I'm new in swift). – Jorge Manuel Bello May 29 '17 at 12:28
3

Swift 4 solution without force optional unwrapping

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let barVC = segue.destination as? UITabBarController {
        barVC.viewControllers?.forEach {
            if let vc = $0 as? YourViewController {
                vc.firstName = self.firstName
                vc.lastName = self.lastName
            }
        }
    }
}