Victor Castro
Victor Castro

Reputation: 1242

access textfield text from another viewController

I try to access a textfield content in my view profileView from my first view viewController but it doesn't work. I read that I have to use override func prepare(for segue: UIStoryboardSegue, sender: Any?) {} so I did but it still not working and I don't understand why.

Here is my viewController code:

// This code is the code generated by xCode, only the loginField was added.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var loginField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

and here is my profileController prepare func:

    var login: String!
    @IBOutlet weak var myLabel: UILabel!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        print("prepare")
        if (segue.identifier == "mainMenu")
        {
            let svc = segue.source as! ViewController
            login = svc.loginField.text
            self.myLabel.text = login
            print(login)
        }
    }

Actually, the thing i really read was "prepareForSegue" func but when I try to override it, xCode won't compile the code...

Thanks for your help.

Upvotes: 1

Views: 5065

Answers (4)

elk_cloner
elk_cloner

Reputation: 2149

write your prepareforSegue method in your viewController

why?

Because you want to send ViewController textfield data to profileViewController.That is write your prepareForSegue in Source. Here,

Source = ViewController

Destination = ProfileView

Note:

  1. Use a variable in your destinationViewController(ProfileView Controller) and keep the textField data in this variable.

like this in prepareForSegue.

 destinationVC.someVariable = self.SourceViewLabel.text // your sourceViewController

and in viewDidLoad of your destinationViewController(ProfileView) write this.

self.profileLabel.text = somVariable

In my first view i wrote this.

@IBAction func nexVCAction(_ sender: Any) {

    self.performSegue(withIdentifier: "secondvc", sender: self)

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier  == "secondvc" {
        let vc = segue.destination as! secondVC
        vc.stringHolder = textField.text!
    }

}

And this is the second view code.

import UIKit

class secondVC: UIViewController {

    @IBOutlet weak var textlabel: UILabel!
    var stringHolder:String = ""
    override func viewDidLoad() {
        super.viewDidLoad()

        textlabel.text = stringHolder

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

I made git project for this.

Check only FirstVC.swift and secondVC.swift

And this is the output.

enter image description here

Upvotes: 5

Yahya Alshaar
Yahya Alshaar

Reputation: 163

You just need a small fix since UITextField and any other components of UIKit are not initialised yet in the prepare for segue:

var login: String!

@IBOutlet weak var myLabel: UILabel!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    print("prepare")
    if (segue.identifier == "mainMenu")
    {
        let svc = segue.source as! ViewController
        login = svc.loginField.text
        // self.myLabel.text = login
        print(login)
    }
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.myLabel.text = login
}

Upvotes: 0

Sergey Gamayunov
Sergey Gamayunov

Reputation: 688

Data flow from one controller to another is the very popular theme for ios beginners. There are several approaches to achieve this goal: segues, delegate pattern, notifications, initialization of new instance of controller, saving data to local storage etc.

You should user prepare(for segue: sender:) method only when you have segue from you current controller to another. You can get access to destination controller instance via destination property of segue parameter.

Also never call IBOutlet properties of destination controller in prepareForSegue - it can be cause of crash, because Outlets may be uninitilized at this time. Instead use String property for example.

Here is sample code:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if (segue.identifier == "mainMenu") {
            if let destinationVC = segue.destination as? ViewController {
               destinationVC.login = self.myLabel.text
            }
        }
}

Where login in destinationVC is the String variable to store login.

Upvotes: -1

Bala
Bala

Reputation: 1304

You cannot set the text of the UITextField and any other components of UIKit in the prepare for segue, because all View components of the recently allocated controller are not initialised yet they are all nil in prepareForSegue. they allocated only be when the viewController is presented.

You set Text for current ViewController TextField at prepareForSegue. Instead of this you should set text at viewWillAppear method while pop or dismiss the presented ViewController by using Notification, Delegate or userDefaults etc...

Upvotes: 0

Related Questions