Reputation: 2209
I am trying to set the text for the UITextField
in the SecondViewController
from the FirstViewController
using the below code:
// First ViewController
@IBAction func buttonAction(_ sender: Any) {
let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
viewController?.sampleTxtField?.text = "world"
if let navigator = self.navigationController {
navigator.pushViewController(viewController!, animated: true)
}
}
// Second ViewController
@IBOutlet weak var sampleTxtField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
print("the textfield value is,\(String(describing: sampleTxtField?.text))")
}
In the log I am getting: "the textfield value is,Optional("")"
I think I am doing some silly mistake. I checked many questions but I am unable find any solution.
Upvotes: 0
Views: 901
Reputation: 12023
When you instantiate a UIViewController from storyboard using instantiateViewController(withIdentifier:)
method it creates a new instance of ViewController and returns it but the UIView and it's elements are not initialised until the UIView is loaded in memory.
ViewDidLoad() gets called when the view controller’s content view (the top of its view hierarchy) is created and loaded from a storyboard. The view controller’s outlets are guaranteed to have valid values by the time this method is called.
So you need to configure your UI element values in ViewDidLoad to have a proper value to these elements.
In you case viewController?.sampleTxtField?.text = "world"
line will not work as Views not yet loaded in memory. To resolve this you need to define a String variable and assign the value after the ViewController is initialised. Then in ViewDidLoad you can assign the String value to the UITextField text property.
class SecondViewController: UIViewController {
@IBOutlet weak var sampleTxtField: UITextField!
var sampleText: String? //it can be var also with default value
func viewDidLoad() {
super.viewDidLoad()
//assign the textField Value here
if let text = sampleText {
self.sampleTxtField.text = text
}
}
}
Now in FirstViewController
you can assign the sampleText property like
@IBAction func buttonAction(_ sender: Any) {
guard let secondViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController else {
fatalError("No ViewController with Identifier "SecondViewController")
}
secondViewController.sampleText = "world"
if let navigator = self.navigationController {
navigator.pushViewController(secondViewController, animated: true)
}
}
Upvotes: 1
Reputation: 627
Make a variable in second viewController like this :
var sampleText: String!
And in viewDidLoad()
of the second view controller write this:
sampleTxtField?.text = sampleText
and in first view controller replace viewController?.sampleTxtField?.text = "world"
line with this:
viewController.sampleText = "world"
This is the standard way to set a value to a textField from another class.
Upvotes: 1
Reputation: 17585
Your code is wrong.
let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
viewController?.sampleTxtField?.text = "world"
In above statment, view's not get loaded in UI so sampleTxtField
always will be nil, Instead create a property in SecondVC, var sample : String?
and assign it as above. Then in SecondVC's viewDidload, assign the value as textField.text = sample
// First ViewController
@IBAction func buttonAction(_ sender: Any) {
let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
viewController?.sample = "world"
if let navigator = self.navigationController {
navigator.pushViewController(viewController!, animated: true)
}
}
// Second ViewController
@IBOutlet weak var sampleTxtField: UITextField?
var sample : String?
override func viewDidLoad() {
super.viewDidLoad()
sampleTxtField.text = sample
print("the textfield value is,\(String(describing: sampleTxtField?.text))")
}
Upvotes: 3