2

I am pretty new to programming with Xcode/Swift and I am facing a small problem.

I want to send information from a ViewController to a second ViewController using delegate and without segue. I read a lot about that and found the most common solution is using the "instance".delegate = self in ViewDidLoad but it just does not work for me.

-- Definition of App --

It's pretty easy. On the first ViewController I have a button and a Label. The button opens the second ViewController, which has a textField and a Button. The Button sends what is in the textField to the first ViewController to update the Label.

-- Code --

This is the code for the first ViewController:

class ViewController: UIViewController, clickedButtonDelegate {

    @IBOutlet weak var Label: UILabel!

    func didClickedButton(text: String) {
        Label.text = text
    }

    var secondView = SecondViewController()

    override func viewDidLoad() {
        super.viewDidLoad()
        secondView.delegate = self
    }
}

This is the code for the second ViewController:

protocol clickedButtonDelegate {
    func didClickedButton(text: String)
}

class SecondViewController: UIViewController {

    @IBOutlet weak var introducedText: UITextField!

    var delegate : clickedButtonDelegate!

    @IBAction func sendData(_ sender: Any) {
        if delegate != nil {
            let information:String = introducedText.text!
            delegate!.didClickedButton(text: information)
            dismiss(animated: true, completion: nil)
            self.navigationController?.popViewController(animated: true)
        }
    }
}

Using this code nothing happens because the delegate is always nil in SecondViewController.

Could you please help?

Thank you in advance!

dndbelart
  • 21
  • 1
  • 3
    When and how do you push SecondViewController? Could you provide that piece of code as well please? – Predrag Samardzic Dec 10 '17 at 02:49
  • This line: `var secondView = SecondViewController()` is you creating some instance of `SecondViewController`. Are you connected to **this** instance? Or you reach to `SecondViewController` through storyboard segues? If that is the case, then you have have to create a pointer to **that** instance and avoid `var secondView = SecondViewController()` – mfaani Dec 10 '17 at 03:01
  • See [this answer](https://stackoverflow.com/a/31934786/5175709) and the video it links to – mfaani Dec 10 '17 at 03:02
  • If the code is so simple and does not contain any sensitive information, you could provide it as a whole.. – Milan Nosáľ Dec 10 '17 at 09:45
  • @Predrag Samardzic: my code is really like that. I connect the two ViewControllers through a Present Modally Segue (see my Answer below). – dndbelart Dec 10 '17 at 16:02
  • @Honey yes, I used a segue. How would you create that pointer? The linked documentation you proposed is using Prepare(for segue) and I would like to use the code above, or at least understand why it doesn't work. Please see my answer below. – dndbelart Dec 10 '17 at 16:05
  • Instead of using segue, you should add action to button on your first view controller, which should do: present(secondView, animated: true). Sounds to me you are mixing 2 aproaches - you are setting delegate to secondView (which you instantiated in code), but you are using segue, thus not presenting secondView, but another instance of SecondViewController (which does not have delegate set). – Predrag Samardzic Dec 10 '17 at 20:31

1 Answers1

0

actually my original code is more complexe. I tried to "reduce the problem" with a much simpler exercice to have a better understanding of how to pass info with and without Segues.

I am connecting both ViewControllers with a Segue (see picture).

Layout

So far I found two ways of passing information that work here:

  1. Segue: by connecting two ViewControllers with a Segue and use prepare(for segue), as following example, and then use protocol functions:

    //This piece of code goes inside the first ViewController
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showSecondView" {
            let secondView: SecondViewController = segue.destination as! SecondViewController
            secondView.delegate = self
        }
    }
    
  2. Instancing: by creating a new instance of the first ViewController and using the info I need from the second View Controller, like in the example code:

    //This piece of code goes inside the second ViewController
    @IBAction func sendData(_ sender: Any) {
        let text_to_pass = introducedText.text
    
        let firstVC = storyboard?.instantiateViewController(withIdentifier: "GetData") as! ViewController
        self.present(firstVC, animated: true)
        firstVC.Label.text = text_to_pass
    }
    

Both options are ok here, but I want to understand why the code above doesn't work. I read a lot of articles and most people is using secondView.delegate = self within ViewDidLoad and working like charm.

What I am doing wrong?

dndbelart
  • 21
  • 1