0

I am using: XCode 8.2, Swift 3.0, iOS 10.2, iPhone 7. I have a Tab Bar Controller with child View Controllers.

I am trying to send data from one view controller to another.

I've looked up how to do this here and here but the first link isn't quite what I want since he is talking about Storyboard segues which doesn't appear to be the same type of segues used when moving between tabs.

The tab in which I am trying to send data:

protocol SendResultsDelegate {
    func sendResults(data: String)
}

class SendingVC {
    ....
    if delegate != nil {
        let data = // some string here
        delegate?.sendResults(data: data!)

    }
}

The tab in which I am trying to receive data and print it out:

import UIKit

class ResultsViewController: UIViewController, SendResultsDelegate {

    @IBOutlet weak var resultsTextField: UITextView!

    func sendResults(data: String) {
        resultsTextField.text = data
    }
}

And I am not sure if this is correct but...I also have a custom class attached to my Tab Bar Controller:

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    let resultsIndex = 2

    if item == (self.tabBar.items! as [UITabBarItem])[resultsIndex] {
        let sendingVC : SendingVC = segue.destinationViewController as! SendingVC
        SendingVC.delegate = self
    }
}

I'm not sure if it should be the tabBar function or the prepare function. I'm basically trying: when the user clicks the results tab, that delegate is set and then passes through the if statement check on the ResultsViewController which can display the text field. Of course, this fails to even compile/build and I am unsure where to go from here. Any help would be greatly appreciated.

Community
  • 1
  • 1
noblerare
  • 10,277
  • 23
  • 78
  • 140

2 Answers2

6

Okay, I figured it out myself that as @Leo Feng said, I don't need to use the delegate pattern. This answer proved helpful: Passing data between tab viewed controllers in swift?

In my case, it was more like:

In the sending view controller:

let secondTab = self.tabBarController?.viewControllers?[2] as! ResultsViewController
secondTab.result_data = // my data here

In the receiving view controller:

import UIKit

class ResultsViewController: UIViewController, SendResultsDelegate {

    @IBOutlet weak var resultsTextField: UITextView!

    var result_data : String? = nil

    override func viewWillAppear(_ animated: Bool) {
        if(result_data != nil) {
            // do stuff with result_data
        }
    }
}
Community
  • 1
  • 1
noblerare
  • 10,277
  • 23
  • 78
  • 140
  • If your app has more than five tabs, this approach is not working, because the order of the tabs can be changed by the user. – lipponen Feb 13 '17 at 11:52
1

I don't think you need to use delegate pattern here. If your tab is selected, your child view controller will load - which it means all the view cycle methods will be called immediately. You can set your data inside viewDidLoad, viewWillAppear and viewDidAppear of your child view controller.

Leo Feng
  • 176
  • 5
  • Hm, okay. So how do I pass data from one child View Controller to another? Is it some type of global variable thing or do I also need to use `protocol` delegates? Some examples would be very helpful. – noblerare Jan 22 '17 at 00:05